Going back to specific commit

We are using github model for our projects. ie: developers send pull requests and then we merge that to master.

We do deployment from the master branch. We do code freeze, do regression and integration testing after that via blue green deployment we go live. We dont do any production deployment without regression and integration testing.

Two days ago, we had a problem, client wanted to do a urgent hot fix. Since I dont have a hotfix branch, I need to go back to the last commit of the last deployment.

How can I go back to previous commit at time T and make the changes, commit then forward to the current time?

1 answer

  • answered 2017-08-12 09:36 VonC

    Git does that all the time on its own master branch.
    It "sandwiches" intermediate versions for fixes between regular development commits for the next release.

    You can see, following the recent security fixes for CVE-2017-1000117, that multiple Git versions have been integrated to master, before resuming the next development cycle:

    vonc@VONC D:\git\git
    > git lg 85df69e47  
    
    *   85df69e47  - (master) Start post 2.14 cycle (8 days ago) Junio C Hamano
    *   4274c698f  - Merge tag 'v2.14.1' (8 days ago) Junio C Hamano
    |\
    | * 4d7268b88  - (tag: v2.14.1, origin/maint) Git 2.14.1 (8 days ago) Junio C Hamano
    | *   230ce07d1  - Merge tag 'v2.13.5' into maint (8 days ago) Junio C Hamano
    | |\
    | | * 7234152e6  - (tag: v2.13.5) Git 2.13.5 (11 days ago) Junio C Hamano
    | | *   e312af164  - Merge tag 'v2.12.4' into maint (11 days ago) Junio C Hamano
    | | |\
    | | | * 3d9c5b5c4  - (tag: v2.12.4) Git 2.12.4 (13 days ago) Junio C Hamano
    | | | *   3def5e9a8  - Merge tag 'v2.11.3' into maint-2.12 (13 days ago) Junio C Hamano
    | | | |\
    | | | | * 3b8274448  - (tag: v2.11.3) Git 2.11.3 (13 days ago) Junio C Hamano
    | | | | *   05bb78abc  - Merge tag 'v2.10.4' into maint-2.11 (13 days ago) Junio C Hamano
    | | | | |\
    | | | | | * 0bfff8146  - (tag: v2.10.4) Git 2.10.4 (13 days ago) Junio C Hamano
    | | | | | *   d78f06a1b  - Merge tag 'v2.9.5' into maint-2.10 (13 days ago) Junio C Hamano
    | | | | | |\
    | | | | | | * 4d4165b80  - (tag: v2.9.5) Git 2.9.5 (13 days ago) Junio C Hamano
    | | | | | | *   af0178aec  - Merge tag 'v2.8.6' into maint-2.9 (13 days ago) Junio C Hamano
    | | | | | | |\
    | | | | | | | * 8d7f72f17  - (tag: v2.8.6) Git 2.8.6 (13 days ago) Junio C Hamano
    | | | | | | | *   7720c33f6  - Merge tag 'v2.7.6' into maint-2.8 (13 days ago) Junio C Hamano
    | | | | | | | |\
    | | | | | | | | * 5e0649dc6  - (tag: v2.7.6) Git 2.7.6 (13 days ago) Junio C Hamano
    | | | | | | | | *   a4f234bf9  - Merge branch 'jk/ssh-funny-url' into maint-2.7 (2 weeks ago) Junio C Hamano
    | | | | | | | | |\
    | | | | | | | | | * aeeb2d496  - connect: reject paths that look like command line options (2 weeks ago) Jeff King
    | | | | | | | | | * 3be4cf09c  - connect: reject dashed arguments for proxy commands (2 weeks ago) Jeff King
    | | | | | | | | | * 2491f77b9  - connect: factor out "looks like command line option" check (2 weeks ago) Jeff King
    | | | | | | | | | * 2d90add5a  - t5813: add test for hostname starting with dash (2 weeks ago) Jeff King
    | | | | | | | | | * 820d7650c  - connect: reject ssh hostname that begins with a dash (2 weeks ago) Junio C Hamano
    * 85df69e47  - Start post 2.14 cycle (8 days ago) Junio C Hamano
    * 4384e3cde  - (tag: v2.14.0) Git 2.14 (8 days ago) Junio C Hamano
    

    As you can see, on master you have only 4 commits (from newest to oldest):

    • 85df69e47 - Start post 2.14 cycle
    • 4274c698f - Merge tag 'v2.14.1'
    • 85df69e47 - Start post 2.14 cycle
    • 4384e3cde - (tag: v2.14.0) Git 2.14 on master

    But the intermediate one "anchors all the intermediate releases that had to be made in order to fix past releases.
    In the "go back to previous commit at time T and make the changes, commit then forward to the current time" sequence, that intermediate 4274c698f commit (the "Merge tag 'v2.14.1'" into master) is the one that allows you to "commit, then forward to the current time".
    You now can resume where you left of in 85df69e47 ("Start post 2.14 cycle").

    So, in your case, you develop your fix on any temporary branch starting from the right old SHA1, then make a commit dedicated to a new tag (in which your VERSION file changes to reflect the new version number about to be released)

    And then you merge it to master.

    But here is the trick: you merge that fix branch in master with git merge --ours. That way, the merge commit is actually empty.

    See any merge commit (at the top of the list of commits above) named "Merge tag 'v2.x.y'".

    It is just there to reference all those fix branches (for 2.14.1, 2.13.5, 2.12.4, ...)
    
    vonc@VONC D:\git\git
    > git lg|grep "Merge tag 'v"
    * | | | | | | | | | | | | | | |   4274c698f  - Merge tag 'v2.14.1' (8 days ago) Junio C Hamano
    | * | | | | | | | | | | | | | | |   230ce07d1  - Merge tag 'v2.13.5' into maint (8 days ago) Junio C Hamano
    | | * | | | | | | | | | | | | | | |   e312af164  - Merge tag 'v2.12.4' into maint (11 days ago) Junio C Hamano
    | | | * | | | | | | | | | | | | | | |   3def5e9a8  - Merge tag 'v2.11.3' into maint-2.12 (13 days ago) Junio C Hamano
    | | | | * | | | | | | | | | | | | | | |   05bb78abc  - Merge tag 'v2.10.4' into maint-2.11 (13 days ago) Junio C Hamano
    | | | | | * | | | | | | | | | | | | | | |   d78f06a1b  - Merge tag 'v2.9.5' into maint-2.10 (13 days ago) Junio C Hamano
    | | | | | | * | | | | | | | | | | | | | |   af0178aec  - Merge tag 'v2.8.6' into maint-2.9 (13 days ago) Junio C Hamano
    | | | | | | | * | | | | | | | | | | | | | |   7720c33f6  - Merge tag 'v2.7.6' into maint-2.8 (13 days ago) Junio C Hamano
    

    Look at the content of any of those commits.

    > git show 4274c698f
    commit 4274c698f46a9bc45834c4904e7e113450c042fb
    Merge: 85df69e47 4d7268b88
    Author: Junio C Hamano <gitster@pobox.com>
    Date:   Fri Aug 4 12:45:17 2017 -0700
    
        Merge tag 'v2.14.1'
    
    () <=== nothing to see there, no diff of any kind.
    
    vonc@VONC D:\git\git
    > git show 230ce07d1
    commit 230ce07d134f597a8107d3ed5d76d212ff90db70
    Merge: 4384e3cde 7234152e6
    Author: Junio C Hamano <gitster@pobox.com>
    Date:   Fri Aug 4 12:40:37 2017 -0700
    
        Merge tag 'v2.13.5' into maint
    
    () <=== nothing to see there either, no diff of any kind.
    

    All those tags are set to ephemeral (hotfix) branches.
    I illustrate the use of ephemeral branches (part of the official "git workflow") in: