将文件从一个存储库更新到另一个存储库中的标记

时间:2014-08-11 19:24:40

标签: git

我有多个与我合作的回购。我需要在其中一个中创建标记,更新文件的修订版并使用相同的标记来更新另一个存储库中的文件。这可能吗? (假设标签被推送到远程服务器)。

或者有没有办法让我可以拥有父远程标记(我不知道如何),并在所有存储库中使用它来更新其存储库中的文件。

repos中的所有文件都是互相排斥的。没有常见文件。这些都是不同的文件夹结构和文件。

感谢您寻找

编辑: 我假设,在git和标签的上下文中看起来这不是一个好习惯。但我会尝试重新编写文件以查看我的问题是否有意义。

基本上,我在Repo A中提交了所有内容。我创建了TagA标签并将其推送到远程服务器。现在,我在Repo B.并且我已经在RepoB中提交了所有内容,比如CommitB。现在,我可以将CommitB添加到TagA吗?

希望这会有所帮助。再次感谢您的光临。

2 个答案:

答案 0 :(得分:1)

不,你不能。因为标签与特定提交相关联。

你能做的最好的事情是:

  1. 删除遥控器上以及从遥控器拉出的每个存储库上的标签(如果您知道谁拥有),包括A.
  2. 使用更新的文件在B上创建标记。推它。
  3. 但是,正如您所看到的,通过这样做,您实际上正在破坏标记的恒定性质。这是不好的做法,因为您没有将标签用于其预期目的,因此您可能追求的是其他内容。

    如果你仔细想想,你真正追求的是git的分支概念。

    1. 您在回购A中创建分支。
    2. 您将其推送到远程服务器。
    3. 你把它拉下来回购B.
    4. 您需要进行任何更改以进行制作和提交。
    5. 您将更新的分支推送到远程服务器。
    6. 现在,当回购A拉动分支时,它会收到更新。
    7. 更新:

      如果每个存储库中的代码完全不同,您仍然需要一种方法来了解构成"发布"的内容。为什么?

      考虑以下情况

      You have 3 repositories:
      Repo A : currently at version 1.7.32
      Repo B : currently at version 3.1.41
      Repo C : currently at version 2.18.28
      

      您需要在此时发布。因此,您可以告诉处理每个存储库的每个人使用相同的标签标记他们当前的版本,或者,您可以通过版本控制构成版本本身的内容:

      Root (this is a repository)
        |- A at 1.7.32
        |- B at 3.1.41
        |- C at 2.18.28
      

      所以,现在,您只需标记根存储库,这意味着当您需要重现发布的代码时,使用您提供的标记检出root,并获得所有其他存储库的版本是。

      这样做的一个结果是A,B或C没有被直接标记。他们为什么要这样?它们可以是许多产品中使用的库。您不希望每个存储库中都有标记用于他们使用的每个产品。

      我们还没有使用正确的术语,但在我看来,您正在寻找的是一种管理存储库层次结构的方法。

      鉴于您从一开始就在单独的存储库中拥有代码的地方开始,您可能希望阅读git subtree

答案 1 :(得分:1)

根据你的编辑,我想也许你所说的可以归结为:

  • 您有一些N(N> 1)个存储库。
  • 在某个时间点,构建系统/所有N个存储库中的任何一个都很有用。
  • 我们假设这是写入DVD或其他任何内容(我们只是将其称为“发布”),然后交给某人(让我们称之为“客户”)。
  • 现在继续工作,N个存储库得到进一步修改(每个存储库独立)。
  • 后来,客户回来说“嘿,当我畏缩的时候,framistan倾销核心。”
  • 现在你/你的小组必须准确地复制你给客户的东西,这样你就可以在观察弗拉米斯的同时尝试擦拭它。

您的问题是:“我可以使用标签准确再现我给客户的内容吗?”

问题的回答是“是的,但是git在这个过程中既不会帮助也不会阻碍你。”为了实现您的目标,您只需标记每个存储库,然后使用标记的文件版本来构建版本:

release=...
tag=...
for (each repository) do
    git clone -n $repository $release/$repository
    (cd $release/$repository; git checkout $tag; rm -rf .git)
done

然后记住您在发布时使用的标记。如果您在所有存储库中使用单个标记名称(例如版本和日期或客户名称等),自助(而不是git帮助您)发布。

当然,当涉及修复客户的问题时,您需要一种方法来更改某些存储库中的某些文件,提交这些更改,并可能标记和构建基于新版本的新版本在那些修复上。您需要保留标记,以便在客户(或某些第二个CustomerB)仍在使用旧版本而不是修补版本时,您可以随意重现该版本。因此,这意味着您每个发布组都有一个分支。同样,在所有存储库中创建分支名称方面,git既不会帮助也不会阻碍您。


如果您正在为QA制作测试(非发布)版本,通常您首先要创建分支 - 这个分支是发布将“来自”的地方,因为它是 - 然后标记所有内容使QA版本就像制作他们测试的真实版本一样。然后,您在分支上进行修复并创建一个新标记。从本质上讲,这些都只是QA的“内部发布”。旧标签可以很快被丢弃(与客户的版本不同)。根据QA是否需要测试两个或更多候选版本,您可能完全没有使用标记,只使用branch-tips作为每个存储库的commit-ID。


另一种选择(在所有各种存储库中标记和/或分支)是制作一个“超级项目”,主要或甚至仅由git“子模块”组成。它的工作方式在概念上相对简单。我最后一次触摸子模块(回到git 1.5.x的时代),但是使用它们非常痛苦。据推测,他们现在至少有所改善。

子模块在基础层面的工作方式是,在“超级项目”中,您记录到各个“子项目”存储库的路径,然后在超级项目中进行提交同时记录每个子项目的确切提交ID。

标记存储库只会为您提供映射到原始提交ID(SHA-1)的符号名称(例如“v1.2”)。所以你收集所有子项目的所有commit-ID并进行提交,实质上,它只有一个这样的列表:

sub-project A: commit ID A234567
sub-project B: commit ID B345678
...
sub-project F: commit ID F098765

超级项目中的这个提交记录了所有这些子项目ID,当然也有自己的ID(也许是5544321)。然后,您可以为超级项目ID提供符号(标记)名称(例如“v1.2”)。现在,您可以从标记(“v1.2”)转到超级项目ID(5544321),然后从那里转到子项目名称和ID(A,id A234567 ) - 这正是你重新创建Release所需要的。如Carl noted in his answer,这可以避免使用标签混淆子项目。 (但是,如果你需要修复一个bug,你通常仍然需要用分支来填充子项目,这样你就有了添加提交的地方。)