Ita*_*ski 45 git push pull rebase
让我来描述我的情况:
Blond先生和Orange先生正在研究分支A,它在提交M1的主分支上分支出来.分支A有2个提交:A1和A2.
M1
\
\
A1 - A2
Run Code Online (Sandbox Code Playgroud)
与此同时,奥兰治先生承诺并在主分公司M2和M3上多推了两笔.
M1 - M2 - M3
\
\
A1 - A2
Run Code Online (Sandbox Code Playgroud)
布朗先生从遥控器拉出来,过了一会儿决定重新进入主分支:
M1 - M2 - M3
\ \
\ \
A1 - A2 A1` - A2`
Run Code Online (Sandbox Code Playgroud)
现在A1`和A2`是在先生金发的本地存在的衍合的提交,以及A1和A2远程存在.金发先生推动他的提交,使用-f强制他的改变并"重写"历史.现在远程存储库看起来像这样:
M1 - M2 - M3
\
\
A1` - A2`
Run Code Online (Sandbox Code Playgroud)
但奥兰治先生也在A分公司工作.他的本地存储库仍然如下所示:
M1 - M2 - M3
\
\
A1 - A2
Run Code Online (Sandbox Code Playgroud)
Orange先生需要做什么才能与远程存储库中的A分支同步?
正常拉动不起作用.请拉-f强制远程本地的更改?我知道删除本地版本的A并从远程存储库再次提供它将会起到作用,但这似乎并不是实现这一目标的好方法.
Gar*_*ler 51
如果Orange先生不介意丢失他的更改,他可以从服务器获取,然后git checkout A2
进入他的本地A2
分支,然后(假设遥控器被命名为"origin")git reset --hard origin/A2
将他重置A2
到遥控器的A2
位置.
如果他担心丢失更改,他可以合并服务器的更改以解决它们(从他自己的A2
分支,并再次假设该遥控器被命名为"origin")git merge origin/A2
.这将使得一个新的提交位于他和远程的A2
分支之上,并且两者的更改都合并在一起.然后可以将其推回遥控器.
Fid*_*tix 36
除非我误解了这个问题,否则奥兰治先生的答案是…… git pull --rebase
。
如果我们假设 A1 和 A2 所做的更改与 A1' 和 A2' 相同(即使它们的提交哈希值不同),那么 Orange 先生可以从
M1 - M2 - M3
\
\
A1 - A2
Run Code Online (Sandbox Code Playgroud)
当地有
M1 - M2 - M3
\
\
A1` - A2`
Run Code Online (Sandbox Code Playgroud)
通过做任何事
M1 - M2 - M3
\
\
A1 - A2
Run Code Online (Sandbox Code Playgroud)
或者
M1 - M2 - M3
\
\
A1` - A2`
Run Code Online (Sandbox Code Playgroud)
如果我们假设,如上所述,A1 和 A2 所做的更改是相同的,并且 Orange 先生做了额外的提交,那么他将在本地拥有
M1 - M2 - M3
\
\
A1 - A2 - A3O
Run Code Online (Sandbox Code Playgroud)
原点将是
M1 - M2 - M3
\
\
A1` - A2`
Run Code Online (Sandbox Code Playgroud)
再次,奥兰治先生可以到达
M1 - M2 - M3
\
\
A1` - A2` - A3O
Run Code Online (Sandbox Code Playgroud)
和
git pull --rebase
Run Code Online (Sandbox Code Playgroud)
如果我们假设,如上所述,A1 和 A2 所做的更改是相同的,Orange 先生进行了额外的提交,Blonde 先生进行了额外的提交,那么 Orange 先生将在本地进行此更改
M1 - M2 - M3
\
\
A1 - A2 - A3O
Run Code Online (Sandbox Code Playgroud)
并且,假设金发先生已经推动,原点将是
M1 - M2 - M3
\
\
A1` - A2` - A3B
Run Code Online (Sandbox Code Playgroud)
橙色先生可以到达
M1 - M2 - M3
\
\
A1` - A2` - A3B - A3O
Run Code Online (Sandbox Code Playgroud)
通过做
git branch -d A
git checkout A
Run Code Online (Sandbox Code Playgroud)
不过,这一次,他可能需要解决冲突。
tor*_*rek 25
我的建议(或者,"如果我是奥兰治先生,我将会做什么")的开头是git fetch
.现在我将在我的回购中拥有这个,这就是金发先生在他的篮板之后以及在他执行"git push -f"之前所拥有的.
M1 - M2 - M3
\ \
\ \
A1 - A2 A1' - A2'
Run Code Online (Sandbox Code Playgroud)
一个重要的区别是,我的本地标签A
指向rev A2,远程标签remotes/origin/A
指向A2'(金色先生反过来,本地标签A
指向A2'并remotes/origin/A
指向A2).
如果我一直在处理名为"A"的分支副本,我将改为:
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2'
Run Code Online (Sandbox Code Playgroud)
(我的本地标签指向A3而不是A2;或A4或A5等,取决于我已经应用了多少更改.)现在我所要做的就是将我的A3(和A4,如果需要等)转换到A2' .一个明显的直接方式:
$ git branch -a
master
* A
remotes/origin/master
remotes/origin/A
$ git branch new_A remotes/origin/A
$ git rebase -i new_A
Run Code Online (Sandbox Code Playgroud)
然后完全降低转速A1和A2,因为修改后的转换器在new_A中为A1'和A2'.要么:
$ git checkout -b new_A remotes/origin/A
$ git format-patch -k --stdout A3..A | git am -3 -k
Run Code Online (Sandbox Code Playgroud)
(该git am -3 -k
方法在git-format-patch
手册页中描述).
这些确实需要弄清楚金发先生在他做之前没有做过的事情rebase
,即识别A1,A2,A3等.
如果第二种方法成功,我最终得到:
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2' - A3'
Run Code Online (Sandbox Code Playgroud)
我的分支名称new_A
指向A3'(我现有的A
分支仍然指向旧的A3).如果我使用第一种方法并且它成功,我最终会得到同样的结果,只是我现有的分支名称A
现在将指向A3'(并且我没有使用A1-A2-A3的旧分支的名称,即使它仍然在我的回购中;找到它需要通过reflogs或类似的).
(如果我的A3需要修改成为A3',当然,交互式rebase和"git am"方法都需要我的工作.)
当然也可以git merge
(就像在Gary Fixler的回答中那样),但这将创建一个合并提交("M"没有数字,下面)并保持转速A1和A2可见,给出:
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2' -- M
\_______________/
Run Code Online (Sandbox Code Playgroud)
如果你想保留原来的A1和A2,这是一件好事; 如果你想摆脱它们,这是一件坏事.所以"做什么"取决于"你想要的结果是什么".
编辑添加:我更喜欢格式补丁方法,因为它保留了我的旧A分支名称,同时我确保一切都很好.假设所有的工作,并为好,这里是最后几个步骤:
$ git branch -m A old_A
$ git branch -m new_A A
Run Code Online (Sandbox Code Playgroud)
然后,如果old_A可以完全放弃:
$ git branch -D old_A
Run Code Online (Sandbox Code Playgroud)
或者,等效地,从分支删除开始,然后将new_A重命名为A.
(编辑:另请参阅git rebase --onto
文档,了解将A3等转换到new_A分支的目标.)
the*_*yer 19
我在两台虚拟机上同时开发,用于配置目的。因此,我经常在一台机器上变基,并且需要毫无困难地将更改显示在另一台机器上。
假设我的分支名为feature/my-feature-branch
。在第一个 VM 上完成 rebase 后,我在第二个 VM 上执行 git fetch。出现以下消息:
$ git status
On branch feature/my-feature-branch
Your branch and 'origin/feature/my-feature-branch' have diverged,
and have 21 and 24 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
Run Code Online (Sandbox Code Playgroud)
好吧,不要执行 git pull,因为在经过一番大惊小怪之后,您最终会得到一个毫无意义的合并提交。
相反,运行
git rebase -i origin/feature/my-feature-branch
一旦文本编辑器弹出,删除所有提交,并将其替换为以下内容(这使得 rebase 完成而不保留任何提交)。
exec echo test
如果您确实有需要保留的提交,那么可以在此处应用这些提交。在任何一种情况下,rebase 都会完成,现在两台机器再次同步,如下所示:
$ git pull
Already up-to-date.
$ git push
Everything up-to-date
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
19572 次 |
最近记录: |