Git 找到重新基准点
假设我有这个:Git 找到重新基准点,git,git-rebase,git-reset,Git,Git Rebase,Git Reset,假设我有这个: I1 -- I2 -- I3 \ \ F1 -- F2 -- ? -- F3 -- F4 -- F5 我创建了一个新的功能分支F,我进行了提交F1和F2,然后我想合并来自集成分支的更改以防止冲突 因此,我: git fetch origin I git checkout F git rebase origin/I 所以它现在应该是这样的: I1 -- I2 -- I3 \ F1 -- F
I1 -- I2 -- I3
\ \
F1 -- F2 -- ? -- F3 -- F4 -- F5
我创建了一个新的功能分支F,我进行了提交F1和F2,然后我想合并来自集成分支的更改以防止冲突
因此,我:
git fetch origin I
git checkout F
git rebase origin/I
所以它现在应该是这样的:
I1 -- I2 -- I3
\
F1 -- F2 -- F3 -- F4 -- F5
我的问题是-现在我想将提交F1-F5压缩为一个提交。我如何才能安全地挤压提交
我可以做git重置--soft x
,但是x
是什么?我如何找到要返回的承诺?我不想失去集成分支的任何历史记录
在英语中,我想这将是我的分支上最古老的提交,它不在集成分支中,但也比来自集成分支的任何提交都要年轻。(?)
git reset --soft HEAD~5
这会将头部指针从其当前位于F5
的位置移回I3
提交。但是,软重置不会同时触及工作目录和阶段。因此,最终的效果将是您的阶段将反映5F
提交。然后,当您提交时,您将有效地将这5个提交压缩为一个:
git commit -m 'squashed 5 F commits'
这就给您留下了:
I1 -- I2 -- I3 -- C
作为替代方案,您还可以执行交互式重基:
git rebase -i HEAD~5
您可以将要挤压的每个提交从pick
更改为squash
,然后完成重基。TL;博士
尝试git-fetch&&git\u SEQUENCE\u EDITOR=“sed-i''s/^pick/squash/”git-rebase-i@{u}
(您可以将其压缩到别名、shell或git-to-shell中)
长的
考虑以下事项:当您运行git-rebase
时,您会告诉git-rebase
将副本放在哪里。也就是说,您运行:
git checkout $branch
git rebase $onto
其中,$branch
是分支机构的名称,$onto
是指定如何进行重基的内容。由于拷贝是在$onto
指定的提交之后进行的,因此$onto
自动成为git重置的正确点--soft
如果您有git pull--rebase
rungit-rebase
,您就放弃了对$的直接控制。git pull
命令首先对一些$remote
运行git fetch$remote
,然后使用git fetch
记录的获取信息(在$git\u DIR/fetch\u HEAD
中)作为$on
参数
由于fork-point代码,这里有一点额外的复杂性,但是在现代Git中,Git fetch
将更新$upstream
,其中$upstream
是当前分支的上游,之后,git-rebase
将使用$upstream
并自动执行所有fork-point操作,以便$upstream
仍然正确。在这种情况下,使用:
. git-sh-setup
branch=$(git symbolic-ref -q --short HEAD) || die 'not currently on a branch'
remote=$(git config --get branch.$branch.remote) || die 'current branch has no upstream'
git fetch $remote && git rebase || die 'fetch or rebase failed'
git reset --soft $upstream && git commit
因为您的脚本(命名为,例如,$PATH
中的git-rebase和squash
,并以git-rebase和squash
的形式运行)主要起到了作用
但是,与直接使用reset--soft
和git commit
不同,您可能希望读取最后一行:
GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick/squash/'" git rebase -i $upstream
这将为您将所有的pick
s转换为squash
es,在这种情况下,您甚至不需要较早的git-rebase
,因此整个脚本将分解为git-fetch
,然后是git-rebase-i@{upstream}
。(是否仍要自动编辑序列取决于您。)
如果您不介意有点误导性的错误消息,您也不需要进行检查。默认情况下,运行git fetch
将从origin
获取,如果没有当前分支或当前分支没有上游,则@upstream
将有噪音地失败,因此这可以简化为两个命令长的脚本或别名:
git fetch && GIT_SEQUENCE_EDITOR="sed -i '' 's/^pick/squash/'" git rebase -i @{u}
向上投票,但我需要以编程的方式做这件事。即使我是手动操作,我也不知道从哪里可以得到神奇的数字5,你呢?编程dogg
。。。我不知道狗会编程,但除此之外,我的答案是编程式的。如果你是从命令行以外的工具使用Git,那么一定要告诉我们你在使用什么。狗不会编程,但狗可以。不管怎样,在现实生活中,您如何确定要返回多少承诺?很明显,返回5次提交并不总是正确的答案。我现在明白了。答案是,您需要找到一些方法来知道有多少提交要重置。例如,如果F
提交总是保证来自您,而I
提交总是来自其他人,那么您可以根据需要返回到除您自己以外的其他人。对,我一直在git日志中往回走,直到我找到一个已经在集成分支中的提交,我猜?因此,从编程的角度来看,似乎只需要以下内容:git-fetch-origin-dev;git-rebase-dev;git重置——软开发代码>是这样吗?换言之,只要我在重置之前做了重基,我就应该是好的。看起来上面的评论是好的,这很好。只要记住检查每个命令的失败退出,因为每个命令都可能由于各种原因失败:例如,git fetch
可能因为网络关闭而无法获取,或者,rebase可能遇到冲突,需要人的帮助。(如果软重置失败,这是最不可能的,因为这是最后一步,所以没有多大关系!)这一切都取决于您希望何时、何地以及如何完成工作。如果要使用git merge--squash
来合并工作并终止功能分支,那么如果要推迟所有工作,可以在最后执行该操作。如果您想更早地完成这项工作,您可以随时重新设置基准。所以,决定你希望什么时候、怎样、在哪里