避免重复提交的Git rebase方法
当我试图从master重新基址到我的开发分支时,我面临一个奇怪的问题。在master和dev分支中都有一些工作正在进行中 为了从主人那里得到改变,我做了如下的事情避免重复提交的Git rebase方法,git,github,version-control,Git,Github,Version Control,当我试图从master重新基址到我的开发分支时,我面临一个奇怪的问题。在master和dev分支中都有一些工作正在进行中 为了从主人那里得到改变,我做了如下的事情 git checkout dev git rebase master 这个很好用。但— 当我执行时,dev分支提交正在重复 git签出开发 git添加。 git commit-m“一些变化” git推送 git重基主控器 在开发分支的git项目历史记录中,提交一些更改正在重复。它还创建循环 如果我在推动开发分支更改之前执行了gi
git checkout dev
git rebase master
这个很好用。但—
dev
分支提交正在重复
git签出开发
git添加。
git commit-m“一些变化”
git推送
git重基主控器
在开发分支的git项目历史记录中,提交一些更改正在重复。它还创建循环
b48659d
是重复的(最初的提交我在dev分支中执行了37c07a4
)第一次推送,然后重新基址
* fbadb86 (HEAD -> dev) Merge branch 'dev' of *******
|\
| * b48659d (origin/dev) sample added in dev branch --> did rebase after push and got this commit again
* | 37c07a4 sample added in dev branch --> commit + push
* | 46c1f40 (origin/master, origin/HEAD, master) master file added in master branch --> commit + push
|/
* 5baae80 first commit
在执行推送之后,所有提交都会发生这种情况。这在重新定基时造成了很多问题,因为提交正在重复,而且即使我自己的代码在以前的提交中发生了更改,也会产生批量冲突。所有提交始终是只读的。它们也是永久性的,除了一些例外(与是否有人能找到它们有关)。这意味着git-rebase
复制提交。这就是我的工作
让我们看看您的git日志--graph--oneline…
输出,但让我们从简单一点开始:
* b48659d (dev) ...
* | 46c1f40 (origin/master, origin/HEAD, master) ...
|/
* 5baae80 first commit
注意缩短的散列ID,例如5baae80
和b48659d
。这些是每个提交的“真实名称”,缩短为7个字符,因为这通常就足够了。1每个提交记录父提交的ID,Git使用这些父提交哈希值从最近的分支提示提交开始,在历史记录中向后跟踪每个提交。分支dev
的提示提交现在是37c07a4…
:
5baae80--46c1f40 <-- master, origin/master
\
b48659d <-- dev
此时,您运行了git-rebase
,这就是开始出错的地方
1Git现在动态选择缩短的长度,而不是总是使用7,但默认情况下它从7开始。您始终可以使用更多:全名当前有40个字符长
重基复制提交,然后移动分支标签
git-rebase
命令无法更改任何现有的提交,因为git中没有任何东西可以这样做。Git的设计就是为了让这成为不可能。因此,它甚至没有尝试。相反,它复制提交
复制提交时,Git需要两条信息:
- 它应该复制什么
- 它应该把副本放在哪里
HEAD
开始向后执行的提交,并在您选择的某个点停止,从而获得要复制的第一个提交列表。(此列表是向后的,因此必须将其反转。)Git从您提供的参数中获取目标“copy after”点的秒数,例如master
在这种情况下,HEAD
namesdev
(因为您在启动重基之前运行了git checkout dev
),因此要复制的提交将以名称dev
指向的副本结束:
5baae80--46c1f40 <-- master, origin/master
\
b48659d <-- dev (HEAD), origin/dev
既然已经复制了整个提交列表,git-rebase
做了最后一件事。它从原始提交字符串中拉出名称dev
,并将其粘贴到新副本上。结果是:
37c07a4 <-- dev (HEAD)
/
5baae80--46c1f40 <-- master, origin/master
\
b48659d <-- origin/dev
该提交之所以存在,是因为您运行了git merge
您可能通过运行git pull
来运行git merge
。默认情况下,git pull
为您运行git fetch
,然后为您运行git merge
。(我建议Git初学者千万不要使用Git pull
:它的功能和方式都非常混乱。将它分成Git fetch
,然后迟早会执行第二个Git命令,有时是Git rebase
,有时是Git merge
)
一般来说,gitmerge
所做的是尝试将两条独立的“开发线”结合起来。给出这样一张图:
37c07a4 <-- dev (HEAD)
/
5baae80--46c1f40
\
b48659d <-- origin/dev
这就是您现在看到的,在git日志--graph--oneline…
输出中(还添加了master
和origin/master
箭头,因为这样画太难了,所以我把它们省略了)
这里的基本错误是在别人已经提交的提交上运行git-rebase
。在本例中,位于origin
的另一个Git已经提交了b48659d
。您无法更改该提交,因此,当您创建新副本时,您将停止使用您的b48659d
,但他们仍然拥有自己的副本。最终,你必须将“他们的”和“你的副本”合并在一起,让这张图片变得相当混乱
(这条规则有一个例外:如果你能说服所有拥有b48659d的人放弃它,并将他们的dev
s转换为使用你的新副本,你仍然可以重新设置基础。但你是否可以,以及如何做,是另一个问题。)所有提交都是只读的,始终如此。它们也是永久性的,除了一些例外(与是否有人能找到它们有关)。这意味着git-rebase
复制提交。这就是我的工作
让我们看看您的git日志--graph--oneline…
输出,但让我们从简单一点开始:
* b48659d (dev) ...
* | 46c1f40 (origin/master, origin/HEAD, master) ...
|/
* 5baae80 first commit
注意缩短的散列ID,例如5baae80
和b48659d
。这些是每个提交的“真实名称”,缩短为7个字符,因为这通常就足够了。1每个提交记录父提交的ID,Git使用这些父提交哈希值从最近的分支提示提交开始,在历史记录中向后跟踪每个提交。分支dev
的提示提交是n
* fbadb86 (HEAD -> dev) Merge branch 'dev' of *******
37c07a4 <-- dev (HEAD)
/
5baae80--46c1f40
\
b48659d <-- origin/dev
37c07a4--fbadb86 <-- dev (HEAD)
/ /
5baae80--46c1f40 /
\ __--------
b48659d <-- origin/dev