简体   繁体   English

在github上执行多个拉取请求

[英]Doing multiple pull requests on github

When I open a pull request on GitHub, all commits since my last request and all new ones are automatically added to this request. 当我在GitHub上打开请求请求时,自上次请求以来的所有提交和所有新提交都会自动添加到此请求中。 I can't seem to control which commits are added and which are not. 我似乎无法控制要添加哪些提交,哪些不添加。

I did the following: 我做了以下事情:

  • Made a fork of repository 做了一个仓库的叉子
  • Made a branch called patch and bugs 做了一个叫做补丁和错误的分支
  • git checkout patch
  • Made a file change 进行文件更改
  • git commit -m "Made a commit"
  • git push origin patch
  • Made the pull request on GitHub from patch 通过补丁在GitHub上发出拉取请求
  • git checkout bugs
  • Made a file change 进行文件更改
  • git commit -m "Fixed a Bug"
  • git push origin bugs

looked at pull request and both commits are present.. I didn't want that. 看着拉请求,并且两个提交都存在..我不想要那个。 What am I doing wrong? 我究竟做错了什么? I figured both commits on different branches. 我发现这两个提交都在不同的分支上。 I am confused. 我很困惑。

Summary 摘要

You need to be careful about branch starting points, and the resulting commit graphs. 您需要注意分支起点和生成的提交图。

Description 描述

In Git, commits can be, and very often are, on more than one branch at a time . 在Git中,一次并且经常一次可以在多个分支上进行提交。 If you are coming from some other version control systems, this can be quite startling. 如果您来自其他版本控制系统,这可能会令人吃惊。 For instance, in Mercurial—which is otherwise very similar to Git in many ways—every commit is on exactly one branch. 例如,在Mercurial中(在其他方面与Git非常相似),每个提交都恰好在一个分支上。 In Git, however, each commit is on zero or more branches simultaneously . 但是,在Git中,每个提交同时在零个或多个分支上

The implications of this reach rather far, but the most immediate one for you is that when you make pull requests on GitHub, GitHub's Git manipulations do things you did not expect. 这种影响的范围很远,但是对您来说最直接的影响是,当您在GitHub上发出请求请求时,GitHub的Git操作会执行您没有想到的事情。 (GitHub—which I have used rather a bit more lately—seems to attempt to hide many of Git's intricacies from users. This has its advantages, since Git's complexity can be intimidating. But it has disadvantages, such as leading you down this particular path.) (我最近已经使用了很多时间的GitHub似乎试图向用户隐藏许多Git的复杂性。这有其优点,因为Git的复杂性可能令人生畏。但是它有缺点,例如使您走上这条特定的道路。)

I will try to avoid going into too much detail here (difficult for me :-) ). 我将尽量避免在这里过分详细(对我来说很困难:-))。 The key to understanding all of this lies in visualizing the commit graph and knowing what, at a sort of fundamental level, a pull request is . 理解所有这些的关键在于可视化提交图,并知道在某种基本水平上拉取请求是什么

The commit graph 提交图

The graph, which is formally a D irected A cyclic G raph or DAG, is formed by the commits you and others make. 曲线图中,这是一个正式的d irected 环状ģ拍摄和或DAG,由您和其他人使提交形成。 Each commit generally has one parent commit. 每个提交通常都有一个提交。 These parents form a backwards chain. 这些父母形成了向后链。 If we start with a completely empty repository (no commits at all) and make a first commit, that commit has no parent, because there's no earlier commit: 如果我们从一个完全空的存储库(根本没有提交)开始并进行第一次提交,则该提交没有父级,因为没有更早的提交:

A

(I'm giving the commits one-letter names here instead of Git's incomprehensible hash IDs). (我在这里为提交指定一个字母的名称,而不是Git难以理解的哈希ID)。 When we make the second commit, it has the first commit as its parent. 当我们进行第二次提交时,它将第一次提交作为其父项。 We say that the new commit B "points to" existing commit A : 我们说新的提交B “指向”现有的提交A

A <-B

This continues on for as many commits as we make: each new one points to some earlier one. 这将继续进行我们所做的多次提交:每个新提交都指向一个较早的提交。 For simple linear chains this is all pretty straightforward, and all we have to do here is add the fact that Git needs a name it can use to find the last commit. 对于简单的线性链,这是所有非常简单,而我们要在这里做的就是添加了Git需要一个名字就可以用它来找到最后提交的事实。 The name we all start out with is master : 我们所有人都以master开头:

A <-B <-C   <-- master

All of Git's arrows are always backwards. Git的所有箭头始终向后。 The ones coming from branch names move around—in fact, master , or whatever branch we are on, gets updated automatically as we add each new commit—so I think it's wise to keep drawing them; 来自分支名称的名称会四处移动(实际上, master或我们所在的任何分支都会在添加每个新提交时自动更新),因此,我认为继续绘制它们是明智的。 but the arrows that tell us that commit C points to B , and B points to A , are fixed forever. 但是,告诉我们将C指向B ,将B指向A的箭头永远固定。 It's easier to draw these without the arrows, so that's what I do. 不带箭头就可以绘制这些图形,这就是我要做的。

Now let's make a new branch name, with something that has lots of commits: 现在,让我们创建一个新的分支名称,其中包含许多提交:

...--F--G--H   <-- master, patch

What we have now is two branch names, both pointing to the same commit! 现在,我们有两个分支名称,都指向同一提交! Commit H is on both branches. 提交H两个分支上。 So are commits G and F and all the earlier ones. GF以及所有先前的提交也是如此。 Now it becomes important to know which branch we're actually on, so let's add (HEAD) to one of these: 现在重要的是要知道我们实际在哪个分支上,因此我们将(HEAD)添加到其中之一:

...--F--G--H   <-- master, patch (HEAD)

Aha, we're on branch HEAD . 啊哈,我们在HEAD分支上。 Let's add a new commit I now: 让我们添加一个新的承诺I现在:

...--F--G--H   <-- master
            \
             I   <-- patch (HEAD)

What Git does is the same as always: it makes the new commit with one parent, so that I points to H , and then it moves the current branch —ie, patch , as indicated by HEAD —so that it points to the new commit. Git的操作与往常一样:它与一个父对象进行新提交,因此I指向H ,然后它移动当前分支 (即HEAD指示的patch ,从而使其指向新提交。

The master branch does not change at all: it still contains commits A through H inclusive. master分支根本不会更改:它仍然包含提交AH包括H The patch branch now contains commits A through I inclusive. patch分支现在包含提交AII

Let's make another new branch now, such as bugs . 现在让我们创建另一个新分支,例如bugs But where will the name bugs point? 但是, bugs名称将指向何处? We have two pretty good options: we can point the name at either commit H , where master points now, or we can point it at commit I , where patch points now. 我们有两个不错的选择:我们可以将名称指向commit H ,现在master指向该位置,也可以将其指向commit I ,现在patch指向。

Whichever one we choose, we can now make a new commit J . 无论选择哪个,我们现在都可以进行新的提交J But J 's parent will be determined by which commit bugs points to once we create bugs ! 但是,一旦创建bugs J的父母将由提交bugs指向的地方来确定! So it's pretty important which one we choose. 因此,选择哪一个非常重要。

When you made your first commit, you chose I , and got this kind of picture: 当您进行第一次提交时,您选择了I ,并得到了以下图片:

...--F--G--H   <-- master
            \
             I   <-- patch
              \
               J   <-- bugs (HEAD)

If you choose H as the starting point, however, you'll get this other picture: 但是,如果选择H作为起点,则会得到另一张图片:

             J   <-- bugs (HEAD)
            /
...--F--G--H   <-- master
            \
             I   <-- patch

Pull requests 拉取要求

A pull request is always, necessarily, done with respect to some existing starting-point. 总是必须相对于某些现有起点完成拉取请求。 If you use the old-school, pure-Git command, git request-pull , you supply the starting point. 如果使用老式的纯Git命令git request-pull ,则可以提供起点。 What GitHub does with their clicky buttons is automate the starting point selection for you. GitHub使用clicky按钮的功能是自动为您选择起点。 But there is a catch: the starting point must be a commit that both you and your upstream repository already share. 但是有一个陷阱:起点必须是您和上游存储库已经共享的提交 (Your upstream, in this particular context, is the repository you forked. The word upstream is a bit ambiguous here: like much of Git's terminology, the word has been overloaded to mean many different things.) (在这种情况下, 上游是您创建的存储库。 上游一词在这里有点含糊不清:就像Git的许多术语一样,该词已被重载以表示许多不同的意思。)

In short, the upstream commit is always going to be whatever their master points to now, or at least, pointed-to earlier (their own master may have moved forward since you forked things). 简而言之,上游提交始终将是它们的 master点指向的,或者至少是指向更早的位置(自您分叉后,它们自己的master可能已向前移动)。 That's going to wind up being commit H in our drawings above. 在上面的图纸中,提交为H

If your graph topology resembles the first one—commit J points back to I which points back to H —then a pull request from that point will include both commits. 如果您的图拓扑类似于第一个图-提交J指向I ,指向H -从该点开始的拉取请求将包括两个提交。 It does not matter that I is on several branches in your repository; I在您的存储库中的多个分支上都没关系; what matters is that commit H is the latest one that you and the upstream repository are both using. 重要的是,提交H是您和上游存储库都在使用的最新提交。 (Again, each of these one-letter names stands in for an actual raw Git hash ID, such as commit 1f931caf22b7... or whatever.) (同样,这些一个字母的名称都代表实际的原始Git哈希ID,例如commit 1f931caf22b7...或其他名称。)

To get just the one J commit to be in your pull request, you need your graph topology to resemble the second one, where H is J 's parent. 为了只将一个J提交提交到您的请求中,您需要使您的图拓扑类似于第二个提交,其中HJ的父级。 The GitHub interface seems—to me at least, though I still have relatively little experience with it—to be very good at hiding the graph topology from you, and thus very bad at letting you view the actual topology and hence see what will really happen with a pull request. GitHub界面似乎(至少对我而言,尽管我仍然相对较少),但善于向您隐藏图形拓扑,因此很难让您查看实际拓扑并因此了解实际情况与拉请求。

When you use command-line Git, you can view (visualize) the topology with the help of "A DOG", a ll d ecorate o neline g raph : 当使用命令行GIT中,可以查看(可视化)拓扑与“A DOG”的帮助下, 一个 LL d ecorateöneline 拉夫

git log --all --decorate --oneline --graph

Various GUIs will also do this for you, eg, gitk --all . 各种GUI也可以为您完成此操作,例如gitk --all This draws the graph vertically, rather than horizontally as I do in these StackOverflow postings, but the idea should be clear enough at this point. 这是垂直绘制图形,而不是像我在这些StackOverflow帖子中那样水平绘制图形,但是此时思路应该足够清晰。

I see in your actions that you didn't git add <files> between made a file change and git commit -m "Made a commit" , as well as between made a file change and git commit -m "Fixed a Bug" . 我在您的操作中看到, git add <files> made a file changegit commit -m "Made a commit"之间以及git commit -m "Fixed a Bug" made a file changegit commit -m "Fixed a Bug"之间没有进行git add <files> That might have some significance. 那可能有一些意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM