我无法弄清楚如何更新分支与另一个分支相同。这是一个例子:
git init test; cd test
echo apple >a; echo banana >b; git add a b; git commit -m 'A1/a:apple;b:banana'
echo carrot >c; git add c; git commit -m 'A2/c:carrot'
git checkout -b second HEAD^1
echo beets >b; echo dandelion >d; git add b d; git commit -m 'B1/b:beets;d:dandelion'
此时我的历史看起来像这样:
A1-----A2 (master, contains a:apple, b:banana, c:carrot)
\
\----B1 (second, contains a:apple, b:beets, d:dandelion)
现在我想向“second”分支添加一个提交,使其内容与“master”分支匹配,即:
A1-----A2
\
\----B1--?--B2 (desired contents a:apple, b:banana, c:carrot)
我的问题是,我运行什么git命令来执行此操作?我最接近的是:
git checkout master .
git commit -m B2
然而,虽然这会将b重置为banana并恢复c,但它不会删除文件d。我无法想出git reset
的任何变体,它可以做我想做的事情。我认为我不想做git revert
的版本,因为在我的实际存储库中,分支上的历史比这个例子更复杂,并且分支可能包含合并。
任何帮助将不胜感激!
答案 0 :(得分:2)
我假设当前分支是second
。如果您对git reset --HARD master
不满意(因为如果second
在任何地方发布,则需要强制推送),您可以git revert B1
撤消B1(如果您不想,则只需git revert master..second
我想列出所有提交,例如B1),然后列出git merge master
。
在ours
策略中使用@StevenPenny构思我提出了这个解决方案:
git checkout master
git checkout -b transfer_second_to_master
git merge -s ours second
git checkout second
git merge transfer_second_to_master
git branch -d transfer_second_to_master
它是theirs
策略的模仿,作为ours
状态的反转来完成。现在git diff master second
没有给出任何东西,它意味着分支是相同的。
答案 1 :(得分:1)
这听起来像是一份工作
git merge
git checkout master
git merge -s ours second
更多信息
This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches.
答案 2 :(得分:1)
你几乎有正确的答案。解决方案是在从master
签出之前先删除所有文件。
git checkout second
git rm -rf .
git checkout master .
git commit -m B2
这将创建一个带有新消息,作者和时间戳的新提交。如果你们都一样,最好的选择是......
下载git-reparent,将其安装在$PATH
,然后
git checkout second
git branch parent
git reset --hard master
git reparent -p parent
git branch -d parent
说明:
second
)。parent
)保存到当前提交。master
)。second
)以获取当前提交的内容但具有给定的父级(parent
)。parent
)。答案 3 :(得分:0)
听起来你只想让分支second
从A2开始。这很简单:
git branch -f second <commit-for-A2>
-f
标志表示“重置分支以提交”。没有理由添加提交来解除/重置second
分支。
[edit]如果您无法简单地重置,请执行B1的恢复(在second
上时),然后将master
中的A2合并到second
。像这样:
ebg@ebg(168)$ git log --graph --oneline --all
* ad6fb9d B1/b:beets;d:dandelion
| * 64c9f45 A2/c:carrot
|/
* 07a4ceb A1/a:apple;b:banana
ebg@ebg(169)$ ls
a b d
ebg@ebg(170)$ git revert HEAD
[second 2b1de0c] Revert "B1/b:beets;d:dandelion"
2 files changed, 1 insertion(+), 2 deletions(-)
delete mode 100644 d
ebg@ebg(171)$ ls
a b
ebg@ebg(172)$ git merge master
Merge made by the 'recursive' strategy.
c | 1 +
1 file changed, 1 insertion(+)
create mode 100644 c
ebg@ebg(173)$ ls
a b c
ebg@ebg(174)$ git log --graph --oneline --all
* 0ffd24e Merge branch 'master' into second
|\
| * 64c9f45 A2/c:carrot
* | 2b1de0c Revert "B1/b:beets;d:dandelion"
* | ad6fb9d B1/b:beets;d:dandelion
|/
* 07a4ceb A1/a:apple;b:banana
答案 4 :(得分:0)
在
A1-----A2 (master, contains a:apple, b:banana, c:carrot)
\
\----B1 (second, contains a:apple, b:beets, d:dandelion)
git status
:clean git read-tree -m -u master
git commit -m 'B2: copy of A2'
git diff master
后:
A1-----A2 (master, contains a:apple, b:banana, c:carrot)
\
\----B1---B2 (second, contains a:apple, b:banana, c:carrot)
git status
:clean diff
状态为master
:clean 确认后退工作:
git reset --hard HEAD^
git clean -f
git branch -avv
再次显示之前的状态。
这个变种做了什么?
git read-tree
将给定的其他提交(此处为master
)读入INDEX -u
,它会相应地更新工作树抱歉,我没有找到正确的方法。这是一个解决方法:
首先:进行虚拟合并
git merge -s ours -m 'B2 dummy' master
第二:将合并修复为正确的数据
git read-tree -m -u master
git commit --amend -m 'B2: copy of A2'
第三:检查它是否与master
匹配:
git diff master
后:
A1-------A2 (master, contains a:apple, b:banana, c:carrot)
\ \
\----B1---B2 (second, contains a:apple, b:banana, c:carrot)
git status
:clean diff
状态为master
:clean 确认后退工作:
git reset --hard HEAD^
git clean -f
git branch -avv
再次显示之前的状态。
这是如何运作的:
git read-tree -m -u master
重置合并信息,所以我们无法启动合并,读取树然后提交此合并,遗憾的是。-u
,因为这对更新工作树至关重要。但-u
需要-m
或类似内容,这会使我们退出合并模式。ours
来防止合并冲突,这正是我们想要发生的错误)。git read-tree
读取大师的状态amend
与现在的,最终正确的索引内容合并。ff
。这有什么问题?
git commit
意味着是原子的。你是否有正确的状态。其他解决方案似乎过于复杂。但也许我会稍微监督一下?
要么使用完全难以理解的git-plumbing命令来自己创建正确的提交对象 - 不需要一个易于理解和使用的解决方案。
或做一些非常复杂的子分支然后快进到子分支,然后删除它 - 双重禁止,因为这甚至引入了更复杂的事情,如复杂的清理需要有些事情会破裂。
或者找出在-u
之后将工作树更新为索引(在[{1}}已经可以执行此操作时重新发明轮子)所需的命令,因为这应该发生在(!)提交之前(像往常一样)。
尚未对子模块进行彻底测试。如果他们被添加,删除,替换等,git read-tree master
和.gitmodules
已更新或阻止某些事情。 Loooooong故事。