1

I need help with a shell script to revert multiple commits in a new branch, then merge the result with one of existing branches. I have 3 branches in my project: dev, live and stage. stage branch is for changes which are testing on stage website, then, after client's approval, they should go to the live branch.

The problem is that the client may not approve all stage changes for deployment (for example, I've done 1,2,3,4,5 tickets each of which was commited in stage branch, but client approved 1,3,4 and requires immediate deploy). So, the task is to merge particular commits from the stage branch with live. My solution is:

  • checkout new branch (deploy)
  • revert commits I don't need in deploy branch
  • merge deploy branch with live

So far I'm reverting changes in deploy branch manually. Now I want to automate this process and I'm trying to create a script for step 2(reverting particular commits in deploy branch). My script is:

git filter-branch -f --commit-filter '
if [ "$GIT_COMMIT" = "8f3859d5f1a5bb75d50f933a0277ba4bca4f2abc" ];
then
    git revert $GIT_COMMIT --no-edit
    git commit -m "Cleaning up revision: $GIT_COMMIT"
fi' HEAD

where in if clause I list all the commits that should be reverted. But after applying this script I always receive a message

Rewrite 8f3859d5f1a5bb75d50f933a0277ba4bca4f2abc (6/13)error: Your local changes would be overwritten by revert.

hint: Commit your changes or stash them to proceed.

But git status command shows, that there are no changes to commit. So, the main question is, why does it work when I execute commands manually but not when I isolate them within a script? P.S. I'm using Git for Windows

Wally Altman
  • 3,535
  • 3
  • 25
  • 33
user2620800
  • 161
  • 1
  • 2
  • 7
  • Would http://stackoverflow.com/questions/11753533/need-to-go-back-to-prev-commit-in-git-how#comment15603638_11753734 help? – VonC Jun 07 '14 at 12:03
  • You should consider using separate feature branches for each ticket; then you could merge only the ones that have been approved by the client and avoid all the mess of reverting. – Wally Altman Jun 07 '14 at 15:35

1 Answers1

2

Rather than mess with reversion, I would use cherry-pick to pull just the commits that the client wants onto live. Then I would reset stage to live to keep stage in sync. If I wanted to retain the commits on stage that weren't approved, I'd tag before reset.

Suppose the client only approves commit a on branch stage. This is the picture.

        /      \ 
       x       a
       |       |
live-> x       b
               |
               c <-stage

    git checkout live
    git cherry-pick a

        /      \ 
       x       a
       |       |
       x       b
       |       |
live-> a       c <-stage

    git checkout stage
    git tag stage "client_submission_yyyy_mm_dd"
    git reset live

              /      \ 
             x       a
             |       |
             x       b
             |       |
live,stage-> a       c <-client_submission_yyyy_mm_dd

Now live and stage have just the commits that client has approved. The commits that the client hasn't approved will be retained because they're reachable from a tag. If the client changes his mind later and wants "That feature you showed me on date xxxx", you can find it from the tag and pick it onto live for him.

The only issue with this is that your dev branch will still contain the rejected commits. They have a couple of options. One option, if they want to drop the rejected commits from their branch, is to reset dev to live as well. If they want to keep working on some rejected commits to get them to a completed state, then they can pick those rejected commits onto dev after reseting.

masonk
  • 9,176
  • 2
  • 47
  • 58