New to git, and already messing up.
I've commited and pushed some changes to a remote dev machine. I need to recover an older version, but keep the "bad progress" doing so far to keep working on a separate branch;
I was thinking doing it like this:
Push to remote
finish tests on tested-thing
Between steps 3 and 5 other developers may commit and push, and I'm afraid this may result on a "merge tragedy" - Anyway, may this be a proper way to go ?
UPDATE:
The main problem here resides on 2)
Here, on topic: "breaking work into a topic branch" http://learn.github.com/p/undoing.html
They suggest:
By doing so, other developers could still:
$ git commit
(on the dev branch)
and I can checkout to test and work it out until merge time.
Despite all your options, this feels like to be a nice approach to follow. However, it's not stated if this can be done after we have pushed ?
Please note the following: Since I made those changes and I mess up the all thing, no one else have worked on the repository so far. So, if I revert the working directory, no one will notice.
Another way of reverting multiple commits is to use the git reset command.
Summary. If you want to test the previous commit just do git checkout <test commit hash> ; then you can test that last working version of your project. If you want to revert the last commit just do git revert <unwanted commit hash> ; then you can push this new commit, which undid your previous commit.
There are a number of work-flows you can use. The main point is not to break history in a published branch unless you've communicated with everyone who might consume the branch and are willing to do surgery on everyone's clones. It's best not to do that if you can avoid it.
Your outlined steps have merit. If you need the dev branch to be stable right away, do it that way. You have a number of tools for Debugging with Git that will help you find the right branch point, and then you can revert all the commits between your last stable commit and HEAD.
Either revert commits one at a time, in reverse order, or use the <first_bad_commit>..<last_bad_commit>
range. Hashes are the simplest way to specify the commit range, but there are other notations. For example, if you've pushed 5 bad commits, you could revert them with:
# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev
# Revert a series using commit hashes.
git revert --no-edit ffffffff..12345678
This will apply reversed patches to your working directory in sequence, working backwards towards your known-good commit. With the --no-edit flag, the changes to your working directory will be automatically committed after each reversed patch is applied.
See man 1 git-revert
for more options, and man 7 gitrevisions
for different ways to specify the commits to be reverted.
Alternatively, you can branch off your HEAD, fix things the way they need to be, and re-merge. Your build will be broken in the meantime, but this may make sense in some situations.
Of course, if you're absolutely sure that no one has pulled from the repository since your bad pushes, and if the remote is a bare repository, then you can do a non-fast-forward commit.
git reset --hard <last_good_commit>
git push --force
This will leave the reflog intact on your system and the upstream host, but your bad commits will disappear from the directly-accessible history and won't propagate on pulls. Your old changes will hang around until the repositories are pruned, but only Git ninjas will be able to see or recover the commits you made by mistake.
If you've already pushed things to a remote server (and you have other developers working off the same remote branch) the important thing to bear in mind is that you don't want to rewrite history
Don't use git reset --hard
You need to revert changes, otherwise any checkout that has the removed commits in its history will add them back to the remote repository the next time they push; and any other checkout will pull them in on the next pull thereafter.
If you have not pushed changes to a remote, you can use
git reset --hard <hash>
If you have pushed changes, but are sure nobody has pulled them you can use
git reset --hard
git push -f
If you have pushed changes, and someone has pulled them into their checkout you can still do it but the other team-member/checkout would need to collaborate:
(you) git reset --hard <hash>
(you) git push -f
(them) git fetch
(them) git reset --hard origin/branch
But generally speaking that's turning into a mess. So, reverting:
The commits to remove are the lastest
This is possibly the most common case, you've done something - you've pushed them out and then realized they shouldn't exist.
First you need to identify the commit to which you want to go back to, you can do that with:
git log
just look for the commit before your changes, and note the commit hash. you can limit the log to the most resent commits using the -n
flag: git log -n 5
Then reset your branch to the state you want your other developers to see:
git revert <hash of first borked commit>..HEAD
The final step is to create your own local branch reapplying your reverted changes:
git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .
Continue working in my-new-branch
until you're done, then merge it in to your main development branch.
The commits to remove are intermingled with other commits
If the commits you want to revert are not all together, it's probably easiest to revert them individually. Again using git log
find the commits you want to remove and then:
git revert <hash>
git revert <another hash>
..
Then, again, create your branch for continuing your work:
git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .
Then again, hack away and merge in when you're done.
You should end up with a commit history which looks like this on my-new-branch
2012-05-28 10:11 AD7six o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six o Revert "another mistake"
2012-05-28 10:08 AD7six o another mistake
2012-05-28 10:08 AD7six o committing a mistake
2012-05-28 10:05 Bob I XYZ nearly works
Better way®
Especially that now that you're aware of the dangers of several developers working in the same branch, consider using feature branches always for your work. All that means is working in a branch until something is finished, and only then merge it to your main branch. Also consider using tools such as git-flow to automate branch creation in a consistent way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With