当我正在处理新代码时,我做了许多小提交来跟踪我的更改。但是,我的公司更喜欢在一次提交中提交每个功能。因此,解决方案是将整个分支压缩为单个提交。
如何在不使用git rebase --interactive
的情况下压缩整个分支,然后将pick
更改为squash
以进行所有提交?
答案 0 :(得分:14)
我的首选方法是双线(不包括下面的步骤1和4)。好处是您不需要知道/记录任何提交ID,您可以编写一个简单的别名来执行所涉及的所有步骤,并实际将整个分支移动到 origin / master以便实际合并成主人可以是快进的,也不会有任何冲突。
首先,我的假设:
my-feature-branch
的分支。这个分支已经从master
分了几次提交;这是签出的分支。master
跟踪远程分支origin/master
my-feature-branch
压缩到当前状态 origin / master (而不是您的本地master
)的单个提交中,这可能是已过期)git reset --hard
期间会丢失)我的流程如下:
抓取,所以origin/master
是最新的:
$ git fetch
将本地分支机构的所有提交重置为origin/master
$ git reset --mixed origin/master
将您之前分支状态的所有旧更改合并到索引
中$ git merge --squash HEAD@{1}
提交您的更改 - Git将使用提交消息预先填充您的编辑器,该消息包含来自压缩提交的所有提交消息
我提到的简单别名是:
alias squash="git fetch; git reset --mixed origin/master; git merge --squash HEAD@{1}"
答案 1 :(得分:7)
可能最好的选择是在合并时使用git merge --squash
。这将使你的分支开发,这通常更容易进行故障排除,因为你会有一些概念“我正在改变提交Z中的特定功能”,并查看该特定提交,你有所有您对多个文件所做的任何更改的上下文 - 查看单个提交,这是您的开发路径的压扁结果使得它更难记住“哦,是的,我必须在另一个文件中更改另一个,也......“。当你拥有整个路径时,你也可以使用git bisect
- 它可以在被压扁的情况下告诉你“这个巨大的提交在这里打破了一些东西”。
使用git merge --squash
的结果是您正在“合并”的分支上的单个提交,其中包含来自分支的累积更改,但它会使原始分支单独保留。
答案 2 :(得分:3)
在启动分支之前找到提交的哈希值并将其复制到剪贴板中。然后重置为该哈希值。
$ git reset [hash]
然后只需在一条消息中重新添加并重新提交更改。
$ git add -A
$ git commit -m 'EVERYTHING SQUASHED'
答案 3 :(得分:2)
编辑您的git配置文件~/.gitconfig
并将以下内容添加到别名部分
[alias]
squash = "!f(){ CUR=`git rev-parse HEAD` && git reset --soft ${1} && git commit -m \"$(git log --format=%B ${1}..${CUR})\"; };f"
此别名获取当前HEAD提交哈希值,重置为您指定的提交,并创建一个保留所有提交消息的新提交。
用法:
git squash <refspec>
refspec可以是任何有效的提交引用,例如提交哈希,分支名称,标记名称,HEAD^
HEAD~3
答案 4 :(得分:1)
这是git reset --soft
的完美用例。
假设您有提交历史记录
D Your latest patch
C Your second patch
B Your first patch
A Someone else's work
您没有阶段性更改,并且git status
,git log
或git show
告诉您当前正在提交D。
然后git reset --soft B
将对提交C
和D
进行累积更改,并将其暂存以进行提交。 git commit --amend
然后将这些更改“合并”到提交B中。
用法如下:
git reset --soft B
git commit --amend
第二个命令将使您的编辑器有机会编辑提交消息。
请注意,如果您在开始此过程之前已进行了分阶段的更改( ie ,您已经完成git add XXX
,但未跟上git commit
),那么这些已分阶段的更改也将是合并到提交中。
答案 5 :(得分:0)
我不认为这是这个问题的正确答案。
但是我通常在使用以下命令向远程上游主机发出Pull Request之前压缩我的分支:
pthread_mutex_lock(&mutex);
if (numItemsProduced < numItems){
printf("Current while loop is at int %d\n", numItemsProduced);
numItemsProduced++;
}
pthread_mutex_unlock(&mutex);
但是你仍然需要选择哪个来挑选和压制。
答案 6 :(得分:0)
The best would be to do a hard reset and merge the previous HEAD with squash. Here is an alias:
[alias]
squash = "!f() { git reset --hard $1; git merge --squash HEAD@{1}; git commit; }; f"
This way you can call it like so:
git squash master
Or to squash from another branch, like dev
:
git squash dev