我正处于一个项目的中间,那里有两个主要的开发分支,因为项目由一个库和一个库的实现组成,这两个分支都在不同的分支中并行开发。
我的工作流程是,一旦将足够的功能添加到库中,我将库分支与--no-ff
合并到实现(名为core
)分支中,理想情况下,库分支应该永远不会看到来自实现,因为否则两个分支都将对相同的实现文件进行更改。不幸的是,情况并非如此,因为我从一个现有的源文件夹启动了该项目,该文件夹中有一些来自库的文件和部分启动的实现,我忘了在最初从master分割两个工作分支时删除实现文件。
工作流:
$ git checkout library
..做出一些改变..
$ git commit -am "updated library"
$ git checkout core
$ git merge --no-ff library
此时我通常必须处理库更新导致的冲突,这些冲突更改library
分支中的实现文件,同时合并core
分支的更改,并更新相同的文件即使core
分支已对这些文件进行了自己的更新。
如果将library
分支中的实现目录合并到实现分支中,如何在不删除它们的情况下删除它们?
答案 0 :(得分:2)
当我将实现目录合并到实现分支中时,如何从库分支中删除实现目录而不删除它们?
您可以使用--no-commit执行合并,恢复已删除的文件并完成提交。
请参阅“git merge: Removing files I want to keep!”作为具体示例。
git checkout dev1
git merge --no-commit dev2
git checkout dev1 implementationFile
git add implementationFile
git commit
答案 1 :(得分:1)
你似乎对此有点不对 - 你不应该为此目的使用分支;相反,您应该使用2个单独的存储库,一个库和一个实现/客户端。然后,客户端将具有库repo,例如,它的子模块(虽然还有其他方法)。
这样,这两个回购之间的文件就不会有任何重叠,这就是你想要的,根据你的要求决定。
为了转换当前以2个分支形式的内容,您将使用git filter-branch
从属于分支B的分支A文件中过滤掉,反之亦然,因此您最终会得到2个repos只有库或客户端的文件(实现)。这当然具有修改历史记录的缺点,因此如果您想避免这种情况,您只需使用普通git rm
和git commit
进行删除。
答案 2 :(得分:0)
cherry-pick
围绕它删除:是的,您可以非常简单地执行此操作:必须避免合并删除文件的提交。所以,当然,你不应该做出改变和删除文件的提交。
示例:
创建一个带有master
分支的git仓库,该分支有两个文件:
~$ mkdir gittest
~$ cd gittest
~/gittest$ git init
Initialized empty Git repository in /home/kaz/gittest/.git/
~/gittest$ echo foo > foo
~/gittest$ echo bar > bar
~/gittest$ git add foo bar
~/gittest$ git commit -m "root commit"
[master (root-commit) 1c1860f] root commit
2 files changed, 2 insertions(+)
create mode 100644 bar
create mode 100644 foo
从根提交中拍摄topic
分支:
~/gittest$ git branch topic
在两个文件的master
上创建第二个版本:
~/gittest$ echo foo >> foo
~/gittest$ echo bar >> bar
~/gittest$ git diff
diff --git a/bar b/bar
index 5716ca5..a486f1a 100644
--- a/bar
+++ b/bar
@@ -1 +1,2 @@
bar
+bar
diff --git a/foo b/foo
index 257cc56..0d55bed 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
foo
+foo
~/gittest$ git commit -a -m "hack 1"
[master ded65d8] hack 1
2 files changed, 2 insertions(+)
切换到topic
。删除bar
并提交。与foo
冲突地修改master
并提交:
~/gittest$ git checkout topic
Switched to branch 'topic'
~/gittest$ git rm bar
rm 'bar'
~/gittest$ git commit -m "delete bar"
[topic 8a4009d] delete bar
1 file changed, 1 deletion(-)
delete mode 100644 bar
~/gittest$ echo "foo2" > foo
~/gittest$ git commit -a -m "replace foo"
[topic abfa329] replace foo
1 file changed, 1 insertion(+), 1 deletion(-)
回顾topic
上的历史记录:
~/gittest$ git log --oneline
abfa329 replace foo
8a4009d delete bar
1c1860f root commit
返回master
:
~/gittest$ git checkout master
Switched to branch 'master'
~/gittest$ git log --oneline
ded65d8 hack 1
1c1860f root commit
现在从主题中挑选abfa329 replace foo
,避免使用8a4009d delete bar
。
$ git cherry-pick abfa329
error: could not apply abfa329... replace foo
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
修复foo
上的冲突并提交:
~/gittest$ cat foo
<<<<<<< HEAD
foo
foo
=======
foo2
>>>>>>> abfa329... replace foo
~/gittest$ cat > foo
foo
foo2
~/gittest$ git add foo
~/gittest$ git commit -m "merged topic, avoiding deletion"
[master 320818f] merged topic, avoiding deletion
1 file changed, 1 insertion(+), 1 deletion(-)
请注意,bar
仍然存在:
~/gittest$ ls bar
bar
~/gittest$ cat bar
bar
bar
git reset
撤消不需要的删除:如果您确实选择了不需要的删除,则可以轻松撤消。
让我们将示例master
分支回滚到hack 1
提交并重写,以便在bar
上不修改master
,仅{{1} }}:
foo
现在,让我们合并~/gittest$ git reset --hard ded65d8
HEAD is now at ded65d8 hack 1
~/gittest$ git reset HEAD^ -- bar
Unstaged changes after reset:
M bar
~/gittest$ git commit --amend -m "hack1: bar only"
[master 623908a] hack1: bar only
1 file changed, 1 insertion(+)
~/gittest$ git log --oneline
623908a hack1: bar only
1c1860f root commit
~/gittest$ git show -p
commit 623908a3bf6b2fb81b0bf8309fa2e83cd602986a
Author: Kaz <kaz@stackexchange.example.com>
Date: Sat Dec 20 08:03:27 2014 -0800
hack1: bar only
diff --git a/foo b/foo
index 257cc56..0d55bed 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
foo
+foo
,而不怀疑有不想要的删除:
topic
糟糕!撤消~/gittest$ git merge topic
error: Your local changes to the following files would be overwritten by merge:
bar
Please, commit your changes or stash them before you can merge.
Aborting
更改后,我忘记了git reset --hard
。拿两个:
bar
好的,合并会自动删除~/gittest$ git reset --hard
HEAD is now at 623908a hack1: bar only
~/gittest$ git merge topic
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Removing bar
Automatic merge failed; fix conflicts and then commit the result.
(因为bar
上没有修改bar
因此没有冲突)。 master
上存在冲突,与foo
案件完全相同,所以让我们先解决这个问题:
cherry-pick
现在,回滚删除~/gittest$ cat > foo
foo
foo2
~/gittest$ git add foo
。请注意,bar
不在工作树中,现在仍然保持这种状态:
bar
我们承诺一切:
~/gittest$ git reset HEAD^ -- bar
Unstaged changes after reset:
D bar
现在我们带回~/gittest$ git commit -m "merged topic, except deletion of bar"
[master 57b7fca] merged topic, except deletion of bar
:
bar
糟糕,我的意思是~/gittest$ git reset
Unstaged changes after reset:
D bar
:
--hard
使用~/gittest$ git reset --hard
HEAD is now at 57b7fca merged topic, except deletion of bar
--graph
验证文件内容。合并了~/gittest$ git log --graph --oneline
* 57b7fca merged topic, except deletion of bar
|\
| * abfa329 replace foo
| * 8a4009d delete bar
* | 623908a hack1: bar only
|/
* 1c1860f root commit
,foo
就在那里:
bar