4

For code review purpose, I want to

  1. cherry pick specific commits
  2. create a new branch with them and
  3. push that branch to remote

so that I can give branch url to peers for review.

I want to create a shell script and issue simple command like

git-review <trackingID>

It gives output as below

Branch <currentgitusername>_<trackingID> created and pushed to remote.

I put together a script that does above mentioned steps.

#!/bin/bash

if [ -z $1 ]; then
    echo "Rationale: Cherry pick all commits in master, matching the tracking ID and create a new branch.";
    echo "";
    echo "Usage:  $0 traackingID";
    echo "";
    exit 1;
fi

#If $1 doesn't match a AGW-<number> pattern, thrown an error
#Best of luck if you did not add add tracking ID in commits.

user="$(id -u -n)" > /dev/null

echo "You are - $user"

branchname=$user"_"$1"_review"

echo "Creating branch - $branchname"

git checkout -b $branchname > /dev/null

git log master --pretty=%H --grep="$1" | while read rev
do
  echo $rev
 # git cherry-pick $rev > /dev/null
done

#git push &> /dev/null

echo "Created branch, cherry picked, pushed to remote. Now switching back to master. Bye."

git checkout master

But got stuck in couple of places.

  1. I want to validate the trackingID format. It should be AGW-<somenumber>
  2. Looks like the cherry-picks have merge issues.

    myname@mymachine ~/myproj
    $ ../git-review.sh AGW-1234
    You are - myname
    Creating branch - myname_AGW-1234_review
    Switched to a new branch 'myname_AGW-1234_review'
    2dfafa89e10062e7cfccb1d7a947ebb848c40cc6
    The previous cherry-pick is now empty, possibly due to conflict resolution.
    If you wish to commit it anyway, use:
    
        git commit --allow-empty
    
    Otherwise, please use 'git reset'
    1e295000bc3d80880518c9cac5e34ef3b28fc29e
    error: Your local changes to the following files would be overwritten by merge:
            rest-service/src/main/java/package/HealthCheckDAOImpl.java
    Please, commit your changes or stash them before you can merge.
    

Am I cherry picking in wrong way ? Also, please suggest any changes to make this script robust.

user229044
  • 232,980
  • 40
  • 330
  • 338
TechCrunch
  • 2,924
  • 5
  • 45
  • 79
  • 2
    It looks like you may be cherry-picking in the opposite order from that in which the commits were originally made. Remember, `git log` puts the newest commits at the top of its output. Also, there's a tool that goes by the name `git review` for interacting with Gerrit, so you may want to pick a different name to avoid confusion. – Phil Miller Feb 26 '15 at 06:45
  • Personally I would suggest you use `git rev-list` instead of `git log --pretty=%H`. It accepts the same options as `git log` but directly prints the SHA1 of the commits. – Sascha Wolf Feb 26 '15 at 07:40
  • @Novelocrat looks like the problem is not only with picking in wrong order. I make some changes. I push my changes to master. Now I am creating a branch out of master and trying to apply some commits with code changes it already has! How to solve this ? Only purpose of this branch for me is to review. We are currently not following branching in our team and everyone directly pushes to master. I failed convincing them to use branching. – TechCrunch Feb 26 '15 at 14:16
  • @TechCrunch You failed to convince them to use branches? Then why even bother using git? That's like buying an cordless screwdriver and then continuing to screw using muscle power. – Sascha Wolf Feb 27 '15 at 11:19

1 Answers1

1

As already pointed in the comments by @novelocrat, You are cherry picking in the wrong order. By default, git log will output from the latest commit to the first commit. To do this, either feed in the output of git log --oneline to tac, or use the --reverse flag:

git log --oneline | tac
git log --oneline --reverse

The second option is obviously prefered, because that ensures line by line output, while the first (using tac) will need to be fed all the input in one go.


Also, since you are creating a new branch out of master, when you do git checkout -b $branchname.

When you do that, all the history of the current branch is picked from that.

So you need to create an orphaned git branch, like mentioned here.

Community
  • 1
  • 1
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
  • looks like the problem is not only with picking in wrong order. I make some changes. I push my changes to master. Now I am creating a branch out of master and trying to apply some commits with code changes it already has! How to solve this ? Only purpose of this branch for me is to review. We are currently not following branching in our team and everyone directly pushes to master. I failed convincing them to use branching. – TechCrunch Feb 26 '15 at 14:17
  • @TechCrunch Oh sorry, should have seen that coming. Basically use an orphaned branch, like mentioned here -> http://stackoverflow.com/a/4288660/1860929 – Anshul Goyal Feb 26 '15 at 15:06
  • To give the start point for orphan, I'm trying to find the commit previous to my first commit. git rev-list master --reverse --grep="AGW-1234" gives my commits. I need to pick first line of this output and append ~1 to it as start point. Stuck with how to get first line of this command output in shell script. Suggestions ? – TechCrunch Feb 26 '15 at 15:12
  • @TechCrunch What do you mean by appending `~1` to it as a start point..? – Anshul Goyal Feb 26 '15 at 15:13
  • 2dfafa89. This is the first commit as a part of bug-fix. If I use 2dfafa89~1 then it will create a branch from parent of 2dfafa89. Then I will cherry pick my bug-fix commits onto this branch. – TechCrunch Feb 26 '15 at 15:16
  • Orphan branch will have all code but just won't have the revision history attached to it. So, it will be same as my master and I cannot write same changes over it again. – TechCrunch Feb 26 '15 at 15:18
  • I had to resort taking grep out of git command. Doing this for now - git log master --pretty=oneline --reverse | grep "AGW-1234" | head -1 | cut -d ' ' -f 1 – TechCrunch Feb 26 '15 at 15:20
  • @TechCrunch No. Orphan branch would be a completely new branch without common history. Re-reading comments, I see that you are trying to merge issues related to a ticket into a single new branch. based on existing history. In that case, modify your script to `git checkout -b $branchname ~1` . I would suggest altering your flow to work on only one ticket per branch; trying to work on multiple tickets on same branch simply does not work if you have good number of bugs spanning over large duration. – Anshul Goyal Feb 26 '15 at 15:24
  • @TechCrunch As a final note, I think your original question has changed significantly now, you should mark this one as answered and ask a new question with your exact issue. – Anshul Goyal Feb 26 '15 at 15:25
  • Thanks for the help. My last question was how to get the SHA_of_first_commit. I found a solution now for it now. Also, as I mentioned earlier, I failed to convince my team to use branching. They are reluctant to use that model with speed of sprint. – TechCrunch Feb 26 '15 at 15:38