【问题标题】:How to create a git branch with custom diff to master branch?如何创建具有自定义差异的 git 分支到主分支?
【发布时间】:2019-05-20 20:37:14
【问题描述】:

抱歉,问题标题含糊不清,我不知道如何更好地表达它。基本上我有一个master 分支,其中有两个提交c1c2

    +-----> dummy1   +-----> dummy2
    |                |
    |                |
    |                |
    |                |
  c1+              c2+
   .                 .
   └── a.txt +       ├── a.txt
                     ├── b.txt +
                     ├── not-wanted.txt +
                     └── c.txt +

c1 已添加 a.txt 文件。如您所见,c2 又添加了三个文件。现在我想要两个虚拟分支,一个来自c1,另一个来自c2,这样当我执行git diff dummy1..dummy2 时,我只能在差异中看到文件b.txtc.txt。所以dummy1<-dummy2 之间生成的 PR 只显示 b.txtc.txt 而不是 not-wanted.txt

这可能吗?

【问题讨论】:

    标签: git git-branch


    【解决方案1】:

    TL;DR:你需要一些 new 提交。您无法通过现有的提交获得想要的结果。

    Git 不是关于分支或文件:Git 是关于提交。拉取请求2 使用分支名称,但只是为了让 Git 可以找到 commits

    换句话说,一切都是关于提交的。名称——像masterdevelop 这样的分支名称,或者像v2.1 这样的标签名称,或者像origin/master 这样的远程跟踪名称,甚至是GitHub 上的拉取请求——实际上只是识别一个特定的提交。每个提交包含个文件——实际上是所有个文件的完整快照——以及元数据,例如谁创建它(用户名和电子邮件地址)、何时(日期和-时间戳),以及原因(日志消息)。

    在一个分支或一个拉取请求中 有多个提交的事实发生是因为每个提交都通过哈希 ID 记录其 提交。每个提交都有自己唯一的哈希 ID,每个提交1 都说 ... 如果您想知道我之前发生了什么,请查看提交 XXXXXX,其中 @ 987654325@s 是上一次提交的哈希 ID。

    因此,在您的设置中,您的 master 上有一系列提交,这些提交要么以 c2 结束,要么继续:

    ...--B--c1--c2--D--E--F--G   <--master
    

    其他人可能在他们的存储库中有一系列以B 结尾的提交。如果是这样,您可以创建一个指向 c1 的名称,从而为您提供:

    ...--B--c1   <-- name1
              \
               c2--D--...--G   <-- master
    

    如果您现在使用 name1 向其他人发出拉取请求,您是在要求其他人(其提交链以 B 结尾)将您的提交 c1 复制到他们的存储库中,并设置一些他们的名字指向c1

    你也可以命名指向c2

    ...--B--c1   <-- name1
              \
               c2   <-- name2
                 \
                  D--...--G   <-- master
    

    并使用您的 name2 发出拉取请求,该请求要求某人将 c1c2 合并到他们的存储库中,并将他们的名字之一设置为指向 c2 .

    无论你做什么,你总是会问他们——不管他们是谁——获取指向现有共享提交 B 的分支名称,这已经在他们的存储库以及你的存储库中, 并将新的提交添加到提交 B 的末尾。您控制的是您要求他们使用的特定提交。他们将从他们的最后的每一个提交——他们的B 的副本——到这个新的提示提交。所以你可以做一个新的提交,我们称之为c3,它在c1之后,你记得通过分支名称name3

               c3   <-- name3
              /
    ...--B--c1--c2--D--E--F--G   <--master
    

    这个提交c3 有你喜欢的任何内容。然后,您向他们发送拉取请求,要求他们设置他们的 master(或任何其他分支名称),以便他们复制提交c1 和@987654352,而不是指向共享提交B @ 进入他们的存储库,然后将他们的名字设置为指向c3

    这样做:

    $ git checkout -b name3 <hash-of-c1>
    ... make whatever changes you like, e.g., git cherry-pick -n <hash-of-c2>
    ... fix things up, git add files as needed ...
    $ git commit
    

    创建新的提交c3,您的分支名称name3 将指向该提交。然后,您可以使用此 name3 名称和新的 c3 提交来发出拉取请求。


    1每个非空存储库中至少有一个提交具有 no 父级:这是第一个提交,它没有先前的提交,因为它不能。一些提交有两个甚至更多的父级:这些是 merge 提交。不过,大多数提交只有一个父级。 Git的历史提交,使用从last提交向后工作形成的向后看链串在一起,通过某个分支名称找到,一次提交一个(或达到合并时有两个或更多)。

    2拉取请求实际上并不是 Git 本身的一部分:它们是附加组件,由 GitHub 和 Bitbucket 等地方提供。 Git 提供的是提交本身和方法——git fetchgit push——用于在对等存储库之间接收和发送提交。在 GitHub 之前,人们会克隆一个 Linux 存储库,进行新的提交,然后通过电子邮件发送补丁以供审查和修订……事实上,他们仍然这样做。

    【讨论】:

      【解决方案2】:

      由于您不希望出现 not-wanted.txt,看来您需要在删除 not-wanted.txt 后创建一个新的提交。

      Delete not-wanted.txt
      git commit -m "c3"
      

      现在从 c1 和 c3 创建两个分支

      git branch dummy-1 c1
      git branch dummy-2 c3
      

      如果你还想在某个分支中备份 not-wanted.txt 文件,你可以在 c2 创建分支:

      git branch backup-branch c2
      

      【讨论】:

      • 如何排除not-wanted.txt
      • 根据要求编辑答案
      • 请注意,如果您只是在c2 之后添加c3(这样c3c2 作为父级),您将向他们发送直到并包括c3 的所有提交.当他们提取c3 时,他们不会看到不需要的文件,但它会在他们现在共享的c2 提交副本中。
      【解决方案3】:

      无需创建单独的分支。您可以区分当前分支中的提交:

      git diff c1 c2
      

      然后,如果需要,使用 diff 创建补丁:How to see the changes between two commits without commits in-between?

      【讨论】:

      • 谢谢,但我需要分支才能有拉取请求。所以 PR 只关注少数文件而不是所有的变化。
      猜你喜欢
      • 2017-10-11
      • 2017-12-15
      • 1970-01-01
      • 2015-04-06
      • 2021-07-05
      • 2019-07-15
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      相关资源
      最近更新 更多