سؤال

Say, you've pushed some commits and pulled them into production, in your server's webroot, for example. And then something goes wrong. Clearly, most often what you want to do is temporarily revert the files in the webroot to some previous state, then go back to your local development place, fix what is broken, test it, commit on top of commits that broke something and push these new fixing commits to the master branch. And then just go to the production webroot again and pull everything to the latest commit so everything is fixed and works correctly. Everyone then can just pull the master branch and not worry about broken commits or resetting git head or other frustrating things.

So: is it a legitimate and safe method to do

In the production webroot, on master branch

>git log --pretty=format:"%h %ad | %s [%an]" --date=short

0fu83bd Wed Mar 6 17:47:42 2013 | Merge branch 'sample' [developer1]
fd442f8 Wed Mar 6 17:47:10 2013 | Some updates [developer1]
ad84471 Wed Mar 6 17:25:12 2013 | Added something [developer2]

find the commit you want to temporarily revert the files state to, say ad84471

>git checkout ad84471
>git branch
* (no branch)
  master

go to wherever you develop, fix, commit, [merge], push master branch. While you do so, the production files are in ad84471 state and no one modifies them. Then back in the production webroot:

>git checkout master
>git pull
>git branch
* master
>git log --pretty=format:"%h %ad | %s [%an]" --date=short
7guffbd Wed Mar 6 17:47:42 2013 | Fixed 0fu83bd bugs [developer1]   <---new commit
0fu83bd Wed Mar 6 17:47:42 2013 | Merge branch 'sample' [developer1]
fd442f8 Wed Mar 6 17:47:10 2013 | Some updates [developer1]
ad84471 Wed Mar 6 17:25:12 2013 | Added something [developer2]

now we are in the master branch, and everything works as should. everyone just pull the latest changes and are good to go.

I've checked the files with md5deep to ensure everything returns (before pulling the fix) to the state we've reverted from:

>md5deep -rel webroot > hashes_master_before_checkouting_ad84471
>git checkout ad84471
>git checkout master
>md5deep -rel webroot > hashes_master_after_checkouting_master_again

the diff between these hashes shows only

webroot/.git/logs/HEAD
webroot/.git/index

had changed.

So it seems like a good method to quickly fix something, or maybe I am wrong?

Disclaimer: I do know that in lots of projects this goes against the intended workflow, and that this practice is not so good, and also that there should be automated testing before, but for small project with few developers it is often not possible or practical, so this method could save a lot of time and simplify the things compared to using git reset or revert.

هل كانت مفيدة؟

المحلول

Seems fine to me for an emergency fix.

If you wanted to be a bit more "rigourous" you could instead create a branch from the "known good" commit and check that out on production, as it leaves a bit more of an audit trail.

On the dev machine:

git branch hotfix-20130307 ad84471
git push origin hotfix-20130307

On the prod machine:

git fetch
git checkout hotfix-20130307

Then after the master branch is fixed, just checkout master again on the prod machine and update it:

git checkout master
git pull

The benefit of this is that if someone goes to the prod machine and runs git branch they get something more informative, and can presumably find some record of the hotfix-20130307 branch in a bug tracker, and know why it was done. If it's a small team and the only people likely to look at the prod machine will already know what the situation is then that might be overkill.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top