我正在熟悉 GIT,只是放弃 svn 并继续使用 GIT。现在我已经弄脏了我的手:
我创建了一个分支并使用 emacs 宏更改了一堆文件,并使用 commit -a 提交了所有文件。我也对其他一些文件做了一些其他更改。在将所有内容合并到 master 之前,我测试了一些东西,并且 emacs 宏缺少一些基本细节。因此,现在大部分批量提交应该被撤消,但不是全部。批量提交后的提交也很可靠。继续恢复大部分批量提交的最简单方法是什么?有樱桃选择实用程序吗?
我目前正在使用命令行 git 和 emacs vcs (git-el)。我买了一本书并浏览了几个网站,但到目前为止我还没有找到满意的答案。
问候,
杰罗恩.
I'm in the process of getting acquainted with GIT, just by ditching svn and continuing with GIT. Now I've made my hands dirty:
I created a branch and changed a bunch of files with an emacs macro, and committed them all with commit -a. I did do some other changes to some other files as well. Before merging everything to the master I tested a few things and that emacs macros lacked a few essential details. So now the greater part of the bulk commit, should be undone but not all. And the the commits after the bulk commit are also solid. What is the easiest way to proceed to restore the greater part of the bulk commit? Is there a cherry pick utility?
I'm currently using command line git and emacs vcs (git-el). I've bought a book and browsed a few sites but so far I haven't found a satisfying answer yet.
regards,
Jeroen.
发布评论
评论(1)
git revert -n <批量提交的哈希>
将尝试反转工作树中批量提交的更改。完成后,您可以运行 git reset HEAD ----patch
一起运行(用于交互式选择要保留的更改)。然后你像任何其他提交一样提交它。您的存储库是私有的/未推送的吗?如果是这样,你还有另一种选择,尽管我不建议这样做。
git rebase -i <批量之前提交的哈希值>
。编辑第一行(应该是批量提交的第一行)以e
或edit
开头。此时,您可以使用 git reset <批量之前提交的哈希值> -- 后跟
git commit --amend
修复批量提交以排除某些文件中的更改。然后 git rebase --Continue 将在调整后的提交之上重写所有剩余的历史记录;如果冲突触及文件的恢复位,您可能必须解决冲突并再次继续。在那之后,你的历史会读起来就像你根本没有做过一些糟糕的改变一样;对于私人项目来说,这可能是一件好事,但请注意,在变基之后,很难回到您正在重写的任何中间状态。您可以使用 git reflog 暂时完成此操作,但最终旧版本的提交将过期并从存储库中删除。无论哪种情况,我建议使用 git diff --name-only 和一些编辑来组合一个文本文件,列出您想要/不想撤消其更改的路径,然后使用shell 构造类似于
$( 在我谈论使用命令行上的路径列表来拉入该文件的地方。每行一个或空格分隔的文件就可以很好地工作的东西。哦,如果路径中有空格,则需要在文件中的路径周围加上引号才能使其正常工作。
git revert -n <hash of bulk commit>
will try to reverse the changes in the bulk commit in your working tree. Once it's done, you can rungit reset HEAD -- <paths to keep changes in>
possibly with--patch
(for interactively selecting changes to keep). Then you commit that like any other commit.Is your repository private/not-pushed? If so, you have one other option, though I don't advise it for something like this.
git rebase -i <hash of commit before bulk>
. Edit the first line (should have the first line of bulk commit) to start withe
oredit
.At that point, you can use
git reset <hash of commit before bulk> -- <paths to revert>
followed bygit commit --amend
to fix your bulk commit to exclude changes in some files. Thengit rebase --continue
will rewrite all of your remaining history on top of the adjusted commit; you may have to resolve conflicts and continue again if they touch the reverted bits of the files. After that, your history will read like you never made some of the bad changes at all; for a private project that may be a good thing, but just be aware that after a rebase it becomes pretty hard to get back to any of the intermediate states that you're rewriting from. You can do it withgit reflog
for awhile, but eventually the old versions of the commits will expire and be pruned from the repository.In either case, I'd advise using
git diff --name-only
and some editing to put together a text file listing paths whose changes you want/don't want to undo, and then using a shell construct like$(< badfiles)
in the places where I talk about using lists of paths on the command line to pull that file in. One per line or space-separated will work fine for that kind of thing. Oh, and if you have spaces in your paths, you'll need to put quotes around the paths in the file for it to work.