提取一系列 git 提交中对单个文件的更改
我使用的构建系统通常要求在执行完整构建之前将项目数据提交到本地存储库。这——加上我在推送到公共存储库之前频繁提交和变基的习惯——意味着我通常在远程头顶上有一堆提交。他们中的大多数人都有像“s”这样的提交消息,因为我知道他们会被压扁。
我这里遇到的情况是自动执行重新调整提交列表的步骤之一。我知道我对某个文件所做的所有更改都不应该推送到公共存储库,并且我正在寻找一种方法来编辑每个提交,以便将该文件的更改拆分为单独的提交,我将在稍后将其压缩变基。
例如,如果源的 HEAD 是我在顶部的提交:
* 6f42745 (HEAD, master-dave) s
* b33bc68 s
* 0b787e8 s
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
我想迭代来自 master..master-dave 的所有提交,提取 更改为 ./file.txt,给我:
* 6f42745 (HEAD, master-dave) s
* ------- DD (changes to file.txt)
* b33bc68 s
* ------- DD (changes to file.txt)
* 0b787e8 s
* ------- DD (changes to file.txt)
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
最后,我将运行 git rebase -i origin/master,压缩所有 “DD”一起提交,所有“s”提交到“使 pkg 与 master 分支保持同步”, 重新排序它们,更新 master,然后推送到原点,最后得到:
* ------- (HEAD, master-dave) DD: dave dev
* ------- (origin/master, master) brought pkg up-to-date with master branch
* 422cf73 Add missing build scripts.
我很确定答案在于 git filter-branch,但我不知道如何实现。
编辑:
- --autosquash 修复了“s”提交的烦恼,但这不是主要问题。我仍然不知道如何将更改拆分到特定文件,这必须在我压缩它们之前发生。
- 涂抹/清洁过滤器很漂亮,但我没有进行关键字替换,而且我认为我想要在个人分支上维护的更改不会足够可预测以编写脚本。我认为我总是必须比公共大师至少领先一项。
The build system I work with usually requires that the project data is committed to the local repository before a full build can be performed. This -- along with my usual habit of committing frequently and rebasing before pushing to the public repo -- means I usually have a stack of commits on top of the remote head. Most of them have commit messages like "s" because I know they will be squashed.
The situation I have here is automating one of the steps of rebasing the list of commits. I know that all the changes I make to a certain file should not be pushed to the public repo, and I was looking for a way to edit each commit to split off the changes to that file into separate commits which I will squash in a later rebase.
For example, here's the commits I have on top if the origin's HEAD:
* 6f42745 (HEAD, master-dave) s
* b33bc68 s
* 0b787e8 s
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
I want to iterate through all commits from master..master-dave, extract
changes to ./file.txt, giving me:
* 6f42745 (HEAD, master-dave) s
* ------- DD (changes to file.txt)
* b33bc68 s
* ------- DD (changes to file.txt)
* 0b787e8 s
* ------- DD (changes to file.txt)
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
And finally, I would run git rebase -i origin/master, squash all
the "DD" commits together, all the "s" commits into "brought pkg up-to-date with master branch",
re-order them, update master, and push to origin, finally ending up with:
* ------- (HEAD, master-dave) DD: dave dev
* ------- (origin/master, master) brought pkg up-to-date with master branch
* 422cf73 Add missing build scripts.
I'm pretty sure the answer lies with git filter-branch, but I can't figure out how.
EDIT:
- --autosquash fixes the annoyance of the "s" commits, but that's not the main question. I still don't know how to split out the changes to a specific file, which must happen before I squash them.
- smudge/clean filters are nifty, but I'm not doing keyword replacement, and I don't think the changes I want to maintain on my personal branch are going to be predictable enough to script. I think I'm always going to have to be at least one commit ahead of the public master.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
http://technosorcery.net/2010/02/07 /fun_with_the_upcoming_1.7_release_of_git_rebase_--interactive_--autosquash.html
这应该告诉你如何自动挤压。不要用 s 标记提交,而是用 !squash 标记它。
看来您应该为所有 DD 提交维护自己的分支。然后只需管理与主分支的合并即可。
如果您想要排除的文件更改是由于环境设置造成的,请改为查看 smudge/clean 脚本。这将使您能够提交对该文件的相关更改,并忽略仅适用于您的环境的任何更改。这通常是一个开发者与另一个开发者不同的数据库连接字符串。
看看这里:http://progit.org/book/ch7-2.html
http://technosorcery.net/2010/02/07/fun_with_the_upcoming_1.7_release_of_git_rebase_--interactive_--autosquash.html
This should tell you how to autosquash. Instead of marking the commit with s, mark it with !squash.
It looks like you should be maintaining your own branch for all the DD commits. Then just manage merging with the main branch.
If the changes to the file that you want excluded are due to environment setup, look at smudge/clean scripts instead. This will enable you to commit relevant changes to that file and omit any changes that are only for your environment. This is usually db connection strings that differ from one dev to the other.
Take a look here: http://progit.org/book/ch7-2.html