Creating a PR on GitHub

The basic process behind a PR is just the following: person A wants to implement feature X, so they clone the repository, create a new branch where they develop feature X. Once the development is finished, they request that their development branch is merged into the master branch. This used to be done (and is also still done) via patches send around on mailings lists. However, GitHub is centered around the idea that you create a development branch for each PR (which is then merged into master) and it works a ton easier if you stick to that.

Git branches are different from branches that you know from subversion. Afaik branches in svn are more or less copies of the entire tree. In git branches are nothing more than "pointers" to a commit (the idea behind that is that you can have thousands of branches alongside each other). The git book shows this quite detailed with some pictures:

With that out of the way, back to the PR. The idea is that you create a new branch that will start at the HEAD of the branch that you want to merge into (that is usually master). Assuming your repository is setup so that the remote origin points to, you can achieve it like this:

git fetch
git branch my_meaningful_branch_name origin/master

With the first command you update all remote branches, with the second you create a new branch starting at origin/master (that is the current state of exiv2/master). Now you can switch to the new branch and start working:
git checkout my_meaningful_branch_name
# do some work now
git commit
# more work
git commit

Now you have 2 additional commits in your local branch my_meaningful_branch_name, i.e. this branch exists only on your machine. You can create a new branch on Github via:

git push -u origin name_of_my_branch_on_origin

There are a few things to note here:

name_of_my_branch_on_origin is the name of my_meaningful_branch_name on the remote origin (that would be github). Those two don't have to be the same, but it is a good idea
the -u flag sets name_of_my_branch_on_origin as the upstream branch, i.e. next time you commit something and push it, you won't have to specify to which branch to push (most times you want it that way)
Now the commits are on github and you can create the PR via the web UI.

Concerning the "branch out of date" message and the additional commits from #213, this is probably caused by you only working on the master branch of your fork and submitting PRs from it. That is possible, but it makes things unnecessarily complicated (on my private fork of exiv2 I don't use the master branch at all, I create new branches from origin/master).

Consider the following initial commit situation:

a -> b -> c (master)
(a, b, c are commits)

You create a new branch starting at c, and create the commit d while someone pushes commit e to master. Now the situation looks like this:

           /-> d (your branch)
a -> b -> c -> e  (master)

This is now the "branch out of date" situation. The issue is, that now you might not be able to cleanly merge your branch on top of master. That's what github is trying to tell you.

The leftover commits from #213 are caused by something similar. You were working in your master branch and added some commits:

      /-> c -> d -> e (your master branch)
a -> b (master)

I then squashed all commits c, d & e from your master branch, creating commit f and pushed it to master (that sounds complicated, but I just clicked the button on github). The situation now looks like this: /-> c -> d -> e (your master branch)
a -> b -> f (master)
Then you want to make another PR and start working on your master branch again adding a commit g:
      /-> c -> d -> e -> g (your master branch)
a -> b -> f (master)

Now github takes a look when your master branch branched of from master. That happened before you started working on the first PR (#213) and so it happily puts all commits since that point into the PR. The branch is also out of date, because it does not contain commit f (which is actually a combination of c, d and e, thus you could easily merge them).

How can you avoid these issues:

Every time you start a PR, fetch everything & create a new branch starting at origin/master
Push the branches to exiv2/ and not to clanmills/. Conceptually there is no difference, but the other devs can write branches on exiv2/ but not on clanmills/. So we could help you in case something breaks.

If the branch should become "out of date" due to pushes to master, please run a git pull --rebase origin master in your PR branch. While this runs a scary rebase, it keeps the commit history linear in contrast to frequent merges (run git log --oneline --graph on your own master branch and you'll see what I mean). You have to do that only once before finally merging a PR (or ask someone else to do it, if the commits are on exiv2/).

If you'll have some time, I would recommend reading the first 3 chapters of the git book.

Updated by Robin Mills almost 4 years ago · 1 revisions