问题
Working with Git, I had to go back to a specific commit. I made some changes and I now want to commit them. What is a proper way of doing this?
My project is now in detached-HEAD state. Will my changes be saved if I make a commit with
git commit
? Otherwise, what should I do to not lose my changes?
回答1:
Disclaimer: git isn't complicated, it's just versatile. Don't be scared off just because I've rambled into a long answer :)
You had:master: a-b-c-d-e-f
and wanted to change c. You did:
* git checkout c (avoid checking out commits in future. Move the branch head instead)
* changed some files
You are in:
master: a-b-c-d-e-f
\uncommitted-work,detached
If you want to re-apply d-e-f on top of your changed "c"
(If you have pushed, people downstream will be have to recover from upstream rebase)
git stash .git checkout mastergit stash pop(resolve conflicts)git stage .git commit -m "temporary name for g"- (
master: a-b-c-d-e-f-g) git rebase c -i("re-apply my current branch on to point c, and let me manipulate the commits interactively", i.e, re-parent (rebase)d-e-fonto a newc)- Follow guide to interactive rebase. You want to re-order
gso it's after c, then change the rebase command frompicktofixup.ddto delete a line,Pto place it,ito enter insert mode to type "fixup" then:wqto save and exit vim. - (
master: a-b-c'-d'-e'-f', wherec'is the result of you merginggandcduring the rebase.d-e-fhave becomed'-e'-f'as their ancestry has changed so they're not the "same" commits as far as git is concerned, but their contents remain the same)
If you want to undo d-e-f (and rewrite history as if you never made them)
(If you have pushed, people downstream will be have to recover from upstream rebase) :
git stash .git checkout master- (
master: a-b-c-d-e-f, with stashed files originally based upon c) git reset --hard c(discard all files and commits on master since c)- (
master: a-b-c, with stashed files) git stash pop(resolve conflicts)- (
master: a-b-c-*) git stage .git commit -m "description of g"- (
master: a-b-c-g)
If you want to undo d-e-f (but keep them in history)
git stashgit revert --no-commit dgit revert --no-commit egit revert --no-commit fgit pushgit stash pop(will be no conflicts)git stage .git commit -m "Undo d-e-f in order to fix..."git push
If you have git push d-e-f, and you want to keep them separate:
Sounds like your new changes are for a new branch off master. git branch <foo>.
回答2:
Create a new branch from this commit and THEN do the commit:
git checkout -b <branchname>
git commit
Assuming you already staged (i.e. git add myfile1 myfile2) your files.
回答3:
to save your work in the detached head:
git checkout -b <new-branch-name-for-detached-head> <sha-of-the-detached-head>
and if you want to merge it to master:
git checkout master
git merge <new-branch-name-you-have-just-created>
来源:https://stackoverflow.com/questions/30983500/how-to-save-changes-when-in-detached-head-state