我使用了一些软件包(比如gitlab),你可以通过他们的git repo克隆来安装。它们通常带有一些legend('indiscernible relation','cernible relation' ,'equivalence relation')
(在版本控制下),您可以将其复制到您自己的config.example
文件中(不受版本控制,甚至可以在config
中忽略)并根据您的需要进行调整。 / p>
更新上游软件包时,例如更改配置文件选项,这些选项显然只会反映在.gitignore
中。
我是否缺少一系列git命令可以帮助我将config.example
的更改与config.example
中的新更改进行比较,甚至可以将它们交互式地合并到我的本地{{1}文件?
如果我能在upstream/HEAD
中获得类似交互式补丁模式的话,那会很棒。
答案 0 :(得分:2)
vim
用作vimdiff
的合并工具。 Emacs
也可以使用ediff-mode
。答案 1 :(得分:2)
你可能会以多种方式解决这个问题。我能想到两个:git-merge-file
和好老patch
。 git-merge-file
方法提供了一些交互性,而patch
方法则不提供任何交互性。
git-merge-file
假设您有一个原始文件config.example
,您可以使用该文件创建本地无版本文件config.local
。现在,当上游更新config.example
时,您可以按照以下步骤合并任何新更改。
$ git fetch
$ git show master:config.example > config.example.base
$ git show origin/master:config.example > config.example.latest
$ git merge-file config.local config.example.base config.example.latest
这将使用通常的冲突标记更新config.local
,然后您必须使用自己喜欢的合并工具解决(Emacs中的ediff
很好,我确定Vim有类似的模式)。例如,以下三个文件
<强> config.example.base 强>:
Original:
some config
<强> config.example.latest 强>:
Original:
some config
Upstream:
new upstream config
<强> config.local 强>:
Original:
some config
My changes:
some other config
将合并为:
Original:
some config
<<<<<<< config.local
My changes:
some other config
=======
Upstream:
new upstream config
>>>>>>> config.example.latest
你可以不费力地编写脚本。顺便说一下,git-merge-file
可以对任何3个文件进行操作,它们不需要在git
下进行版本控制。这意味着可以使用它来合并任何三个文件!
patch
的解决方案:假设文件名相同,config.local
和config.example
,以下内容应该有效。
$ git fetch
$ git diff master..origin/master -- config.example | sed -e 's%\(^[-+]\{3\}\) .\+%\1 config.local%g' > /tmp/mypatch
$ patch < /tmp/mypatch
答案 2 :(得分:2)
git checkout --patch
选择差异,这里最简单的可能是将你的内容放在上游路径上,做到这一点,然后清理:
cp config config.example
git checkout -p upstream config.example
mv config.example config
git checkout @ config.example
它将为您提供git add --patch
的双差异大块选择。
答案 3 :(得分:1)
如果你想要完整的git合并,你可以通过设置一个索引条目git read-tree
来获取任意内容的git,然后在该条目上调用git的普通合并驱动程序。 Git将不同的内容版本称为“阶段”;他们是1:原来的,2:你的,3:他们的。合并比较从1到2和从1到3的变化,并做它的事情。要进行设置,请使用git update-index
:
orig_example= # fill in the commit with the config.example you based yours on
new_upstream= # fill in the name of the upstream branch
( while read; do printf "%s %s %s\t%s\n" $REPLY; done \
| git update-index --index-info ) <<EOD
100644 $(git rev-parse $orig_example:config.example) 1 config
100644 $(git hash-object -w config) 2 config
100644 $(git rev-parse $new_upstream:config.example) 3 config
EOD
并且您已为该路径合并了自定义内容。现在去做:
git merge-index git-merge-one-file -- config
它会自动缓存或保留通常的冲突粪便,根据需要进行修复,并根据需要git rm --cached --ignore-unmatch
(或保留)索引条目。
顺便说一下,您放入索引的路径名(此处所有三个条目中的“config”)不一定存在或与任何事情有关。你可以将它命名为“wip”或“deleteme”或任何你想要的东西。合并是索引条目中id'd的内容。
我认为这可能会在这里做你想做的事。如果您确实想要从上游更改中进行选择,您可以将自己的内容放在config.example并执行git checkout -p upstream -- config.example
,这与git add -p
相反,然后按照它们的方式回放
答案 4 :(得分:0)
要使用config.example
中的相应文件在本地仓库中区分upstream/HEAD
,您可以运行:
git diff upstream/HEAD config.example
不幸的是我不知道如何让git直接将更改应用于git不跟踪的文件。
答案 5 :(得分:0)
有a tool called sdiff可能会做你想要的。
使用sdiff -o config config.example config
答案 6 :(得分:0)
以下内容应该有效:
git diff <some-args> | perl -pe 's/path\/to\/changes\/file/path\/other/g' > t
patch -p1 < t
rm t