Git中的分支特定行

时间:2018-04-03 07:55:48

标签: git git-branch

很抱歉,我的问题很模糊,但我真的不知道如何最好地描述这种情况。

在我的存储库中,README文件包含一个链接,其中有相应分支的分支名称masterdevelop(只有那两个分支受到影响,我不知道真正关心如何处理不同的分支机构)。我现在想要的是,如果我将develop合并到master中,则会保留这种差异。

我到目前为止所做的是使用

git merge --no-commit develop

手动修复链接。这里的问题是,develop具有master的独立历史记录。因此,git describe分支中的develop不包含master上的最新标记。然而,我使用它进行版本控制,因此必须具备此功能。解决方法是将master合并回develop

git merge --no-commit master
然而,这会导致一个混乱的历史,因为我有很多这些空的后合并。

我还尝试了this,我添加了README.rst merge=ours。但是,这会忽略对README所有更改,因此我必须手动更新README文件。

我真的不知道是否有合适的方法。有没有办法告诉GitHub忽略链接(例如通过正则表达式)?或者可能是一些扩展到分支名称的命令?

1 个答案:

答案 0 :(得分:2)

你不能(完全)得到你想要的东西。根据您的需要,您可以获得所需的物品。在检出文件时,请考虑使用涂抹过滤器来更改文件。您需要一个相应的清理过滤器来消除污迹,以便实际提交中的内容不会被污染。

有关设置涂抹和清洁过滤器的详细信息,请参阅the gitattributes documentation

背景

首先,请记住,分支名称只是指向(单个)提交的可移动指针。还有一些人们也会使用 branch 这个词来引用它,它是:由特定提交结束的一系列提交。有关这方面的更多信息,请参阅{{3 }}

一般来说,Git所做的是添加提交。你看看一些分支名称:

$ git checkout master

然后做一些工作(在工作树中的文件,然后使用{复制到临时区域又名索引 {1}}覆盖已经在索引中但与当前提交匹配的副本 - 我们将稍后回到所有这些:)

git add

最后,您运行... edit ... $ git add README.rst ,其中:

  • 收集您的日志消息;
  • 立即打包所有索引中的文件;和
  • 使用这些(加上您的姓名,电子邮件和时间)进行新的提交。

当您运行git commit时,新提交的父提交是您签出的提交。当您运行git checkout master时, new 提交将成为您选择的分支顶端的提交。所以名称 git checkout master现在指向 new 提交,它指向刚才master提交的内容:

master

您一次只能检出一个分支,而... <-previous-tip-of-master <-new-tip-of-master <--master 通过将名称指向 分支专用的新提交Git刚刚提交的新提交。所有其他分支名称都保持不变:它们仍然指向其他一些提交。

使用git commit仍然只是进行新的提交!这个新提交与git merge所做的其他新提交之间的区别在于,这个新提交有两个父项:它像往常一样指向上一个提交,但它也指向了在运行git commit时选择的提交。无论如何,这个新提交只是 on 你所在的分支:

git merge

其中...--B--...--o--C--M <-- master \ / o--...-o--D <-- develop 是新的合并提交。这个新的合并提交有一个所有文件的快照,就像每个其他提交都有一个所有文件的快照一样,因此M中的README.rst文件是通过M中的快照来构建的。 {1}} - 刚才C的提示 - 以及master中的快照,仍然是D的提示。这些&#34; somethings&#34;基于developC自提交{{1}中快照的合并基础提交版本D后的更改方式}。

利用这个:涂抹和清洁过滤器

现在,连同有关谁创建,何时以及使用什么日志消息的元数据,每个提交只是记录当时您在索引/暂存区域中的所有源文件跑了README.rst。当B 派生自此快照时,您获得的结果,但不一定此快照相同。

所有这些细节都很重要! Git会将git commit中的提交提取到index / staging-area中。此时中此索引/暂存区中的内容完全匹配 git checkout <thing-that-specifies-commit>内的任何内容。但这不是您在工作树中看到的内容。您在工作树中看到的内容是通过运行您通过定义的任何涂抹过滤器复制到索引中的任何Git获得的。

默认涂抹过滤器基本上是&#34;保持一切不变&#34;。您可以在此时进行行尾调整。从技术上讲,这与涂抹过滤器是分开的,但它都是这个涂抹过程的一部分。如果您使用此默认值,工作树中的内容与索引中的内容相符。

但是,假设您定义了一个专门应用于M的涂抹过滤器。进一步假设您编写此涂抹过滤器以查找包含应该提及分支MREADME.rst的链接的行。使用正确的链接将您的涂抹过滤器写入替换此行。例如,您提交的行可能应为:

master

你的涂抹过滤器说:

develop

(使用Linux / Unix / GNU blah blah link:!replace this part! blah 命令,但你可以写这个,但你喜欢)。让涂抹过滤器代码确定要使用的分支名称,例如,运行sed -e "s/!replace this part!/actual link using $branch/"

这意味着文件sed的工作树中的内容将不再匹配实际提交的内容

为了使这项工作正常运行,您需要将git rev-parse --abbrev-ref HEAD写为要提交的内容,其中包含以下内容:

README.rst

要自动执行此操作,请自行编写 clean 过滤器,找到污迹线 - 但是您选择这样做 - 并使用git add替换它,例如blah blah link:!replace this part! blah 。 1}}文字。

现在当你跑:

sed

Git将通过干净的过滤器运行工作树文件,以便将!replace this part!的版本写入索引/暂存区。

这在合并时也有效:合并将&#34;参见&#34; 已清理版本的文件,并使用已清理的文本合并您在任一分支上所做的任何更改。 &#34;脏&#34; (污迹)版本具有实际链接仅出现在工作树中。它永远不会进入任何提交。

这是否符合您所需要的内容取决于读取链接的内容。如果有什么东西读取链接,通过提取工作树的提交,并使用涂抹过滤器,那么读取文件将读取污染的实际链接。如果读取文件的东西以某种方式绕过所有这些并获得原始的承诺内容,它将会看到&#34; clean&#34;链接。

如果将已清理的链接存储为适合大多数用途的版本,并且只需要在工作树外使用时指向$ git add README.rst 而不是README.rst的脏版本,这将有效即使是那种情况也是如此。