Home > Git > Showing commits not yet on master

Showing commits not yet on master

I use git most days now, it means I can work on my laptop and commit back to our subversion repository when I am connected again ( or when I finish working on the feature ).

As I have posted previously, I cannot dcommit multiple commits – git freaks out and makes a mess of things after the first commit. To get around this, I do all my work on a topic branch and then cherry-pick the commits from the topic branch into master and dcommit each one individually.  While this works, it is painful so I am slowly working out how to get the list of commits and cherry-pick then dcommit them individually by stringing a bunch of commands together.

The first thing I need to do is get a list of the commit hashes that need to be cherry-picked from the topic branch.


git checkout master
git log master..<topic_branch> --format="%h" > commits.txt

This gives me a nice list of commit hashes that I can use to issue the cherry-pick commands. Beware – at this point the list is in inverse commit order – that is, the oldest commits are at the bottom of the list.

I will keep updating this post as I get closer to having a single command that I can issue to mimic the following ( that I can use due to some weird error )

git checkout master
git svn rebase
git rebase <topic_branch>
git svn dcommit
git branch -D <topic_branch>

Update … with very little research and effort I have managed to create a bash script that mimics the workflow above.
The following bash script gets a list of the commits that are on the topic branch but not in the master in chronological order oldest first and replays them onto the master, one commit at a time, dcommitting the changes between each commit. Ironically, while I was researching / writing this script I may have found the solution to my issue – git svn dcommit --no-rebase.


#!/bin/bash
echo `git checkout master`
echo "Rebasing against remote svn repository"
echo `git svn rebase`
for commitHash in `git log master..$1 --reverse --format="%h"`
do
echo "Merging next commit"
echo `git cherry-pick $commitHash`
echo "Commiting changes to remote repository"
echo `git svn dcommit`
done
echo "$1 successfully merged and dcommitted - don't forget to delete the branch"
exit 0

The script can be put anywhere that is on the bash path – I currently leave it in the root of the folder I am working in ( same folder that houses the .git folder ). Calling the script is as simple as dcommit <topic_branch>.

Advertisement
Categories: Git
  1. Jeff
    August 28, 2009 at 2:09 am | #1

    This seems like more work than necessary. Trunk should be considered the master. After all, it is tracking your svn repo. I never use the initial master branch.

    After you svn init, create a topic branch based on the remote branch (“trunk” if you used -T in init – git-svn if you didn’t – use git branch -a to check or peak at .git/config).
    $ git checkout -b topic/a trunk

    Do your work.
    $ touch newfile.txt
    $ git add newfile.txt
    $ git commit -m “New file.”

    Rebase to bring your topic branch up-to-date with the svn repo, and play your changes on top. Rebase will fetch the latest from the svn repo then perform the topic branch rebase.
    $ git svn rebase

    Commit changes to svn repo
    $ git svn dcommit

    Start new topic branch based on trunk.
    $ git checkout -b topic/B trunk

    • Neal
      August 28, 2009 at 8:38 pm | #2

      Jeff,
      Thanks for your comment. I have tried the approach you suggested but unfortunately that does not work either.

      I usually clone the trunk as I rarely use svn branches or tags during development ( they are useful for releases etc though but managed via build scripts usually ). The reason I have to do all the extra work is that when I dcommit multiple commits, the rebase between each commit fails. I have also tried git svn rebase / git rebase topic_branch / git svn dcommit –no-rebase and while this does not “unroll” commits, it does still fail when there are multiple commits. The bash script is a workaround that I have to use due to something conflicting somewhere in my system.

  1. April 26, 2010 at 4:08 pm | #1

Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

Please log in to WordPress.com to post a comment to your blog.

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.