Hot fix between two remote git


I have two remote git repositories, one is test and the other is production

git remote -v
produccion      https://[email protected]/deploy/pr1.git (fetch)
produccion      https://[email protected]/deploy/pr1.git (push)
test    https://[email protected]/deploy/pr1_test.git (fetch)
test    https://[email protected]/deploy/pr1_test.git (push)

you work in the test, you do the

git push test master

testing does the pull, test the change and if it's ok it goes to production

git push produccion master

The problem is when the test has many functionalities to test but you have to make a hot fix of a change without passing all the commits

example :

repositorio de test : 
test commit 6 - hotfix (se arreglo algo) 
test commit 5
test commit 4
test commit 3 - hasta acá esta igual que produccion
test commit 2
test commit 1
repositorio de produccion: 
produccion commit 3
produccion commit 2
produccion commit 1

I want to upload commit 6 to the production repository without uploading commit 4 or 5

Is it possible to do the push of a single commit without passing the previous ones?


asked by Pablo 17.05.2017 в 22:32

2 answers


It seems like it's a perfect occasion for git cherry-pick .

Cherry-pick (literally, choose cherries ; really, manipulate ) consists of taking a commit from one branch and putting it in another.

Therefore, the ideal in this case would be:

  • Leaving master (what is in production) creates a hotfix of the type hotfix-this_not_functioned.
  • Post these changes.
  • Get the SHA of the commits with the changes, say XXX.
  • From the branch where you want to introduce these changes, execute:

    git cherry-pick <hash-del-commit>
  • answered by 25.05.2017 в 14:11

    The solution depends on whether in test commit 4 and test commit 5 you modified the same or the same files that are modified in test commit 6: hotfix

    In the optimistic case, where your hotfix does not touch what is contained in commits 4 and 5, it will probably help you do what it says @ fedorqui .

    Suppose your commit history is as follows

    946db3c1e commit 1
    f74e10d42 commit 2
    24177c9fe commit 3 # igual a producción
    6409d80f1 commit 4
    7294e5d11 commit 5
    ce322c2b2 commit 6 # aplica hotfix

    Then you could do

    git checkout -b hotfix  // creas una nueva rama llamada "hotfix" desde master
    git reset --hard 24177c9fe // vuelves al último ancestro común con producción
    git cherry-pick ce322c2b2 // aplicas el commit 6 encima del 3
    git push production hotfix:master // pusheas el hotfix hacia producción

    The problem, even if we are on the happy path and commit 6 does not touch the modifications of commits 4 and 5, the cherry-pick that you just made applies the same changes to commit 6 but it has a hash different .

    In production it could be, for example:

    946db3c1e commit 1
    f74e10d42 commit 2
    24177c9fe commit 3 # igual a producción
    eabcfebdb commit 6 # aplica hotfix

    The commit 6 hash in production is not equal to the commit 6 hash in master.

    My suggestion would be to take rebase .

    git rebase -i HEAD~3

    You will see a list with the last 3 commits

    pick 6409d80f1 commit 4
    pick 7294e5d11 commit 5
    pick ce322c2b2 commit 6 # aplica hotfix

    You can reorder them and leave instead:

    pick ce322c2b2 commit 6 # aplica hotfix
    pick 6409d80f1 commit 4
    pick 7294e5d11 commit 5

    When saving, you will rewrite the history of those that you reordered, leaving for example

    pick e7985db68 commit 6 # aplica hotfix
    pick 454f2a7b7 commit 4
    pick f6349516a commit 5

    This means that your local branch will have diverged from test / master and you will have to do

    git push test master -f

    to get back on par with the test repo.

    Now you return to the commit of the hotfix and do the push to production (assuming you were approved by the hotfix)

    git reset --hard e7985db68 // el nuevo hash de commit 6
    git push production master

    Once this is done, you can go back to the most recent commit, which is now called "commit 5"

    git reset --hard f6349516a // el nuevo hash del commit 5

    Now, if in commits 4 and 5 you modified the same files as in commit 6 , when applying the rebase you will be arguing for conflicts (if you add a line in the commit 4 and modify it in 6, it does not make sense to modify it before adding it ...). You will have to resolve these possible conflicts to finish the overflow, but the important thing is that when you finish that step you will be able to go back to commit 6, push to production, and then return to commit 5, which happened to be the most recent.

    Note to the margin

    It seems to me that the workflow they have implemented is confusing. When they receive the approval to "go to production", instead of doing it through a Pull Request, which is the way specifically designed to handle this operation, they do a push to the remote production, which generates an implicit merge that does not leave history of changes, is not subject to continuous integration checks, test coverage, unit tests, etc. nor can you receive comments or corrections, but the feedback I guess you get verbally, by chat or by mail.

    It would be much easier if they used the same repo and worked in different branches. Github allows to determine that certain branches are protected and only one admin can merge a certain pull request to those branches, while the rest of the developers work in temporary branches to address features or hotfixes.

    answered by 12.06.2018 в 23:43