Pull Requests
Working together on a shared repository can be very frustrating, as you have to be very aware of what everyone else is doing, and have to continually think about merging everyone’s changes together.
One way to simplify this process is to use branches. We used branches before when we wanted to edit an old version of versioned_dir
. The most common use of branching is to allow you to work on your own, personal branch of the code, safe in the knowledge that conflicting changes will not be made by others. You can then merge in your changes by merging in your branch, e.g.
o-o-o-o-o master
`o-o' my-branch
The above diagram shows that you have created a my-branch
branch from master
, which you have edited and committed. Meanwhile, there have been other commits made to master
. You have then merged my-branch
into master
, and then further commits have been made to master
.
Branch in the cloud
First, we will create a branch of the “original” versioned_dir
, which will be pushed to the cloud. We will call this branch new-feature
(in general, it is good to call your branch something that indicates the purpose of the branch, e.g. what feature is being implemented).
git checkout -b new-feature
This will create and switch to a new branch called new-branch
.
Now, push this branch to the cloud repository.
git push origin new-feature
(remember, we earlier created an alias that said that origin
was equal to https://github.com/USERNAME/versioned_dir.git
, where USERNAME
was your GitHub username)
This command pushes to origin
your new-feature
branch. This will fail if a branch with this name already exists. It is good practice to ensure that your branch has a unique name, e.g. it includes part of the your username.
If you look on GitHub, you should see that the new-feature
branch is visible in the “Branch” dropdown, e.g.
Working on your branch
Now that you have your own branch, you are free to make changes to it without worrying about conflict (assuming no-one is so rude to make changes to your branch!). Let’s make some changes, e.g. edit README.md
to read
# Hello Brilliant, Useful GitHub
This is a README.md file that will be used to describe this
repository on GitHub
This is a much improved introduction that includes a
new list of items
* Item 1
* Item 2
* Item 3
This is an extra line of text added to the copy
of README.md in the cloned repository
Save the file and then commit the change
git commit -a
Now, when we push, we need to tell Git to push changes from our local new-feature
branch to the cloud new-feature
branch. To do this, we run a modified git push
command
git push --set-upstream origin new-feature
This changes the branch we push to on origin to new-feature
. Note that we only have to do this once, when we first push to the new-feature
branch.
Pull Requests
Once you have finished implementing your new feature, you need to tell all of the other developers that you are ready to merge. To do this, you issue a “pull request”. A “pull request” is a request to the other developers that they should pull in the changes made in your code.
To issue a pull request, use your browser to navigate to your project on GitHub. Change the viewed branch to new-feature
, and then click the green “Compare and pull request” button, e.g.
This will open a form in which you can send a message requesting that the changes in your branch are pulled into master
(you can issue pull requests to merge into other branches by clicking on the “base:master” button and choosing a different branch).
There is a space for you to add a message, which you should use to describe your changes and say why your branch should be merged.
GitHub will automatically check whether your pull request can be automatically merged. In general, it is good practice for you to merge as much as you can yourself, so that it is as easy as possible for others to merge your branch. However, where this is not possible, make sure you say why you cannot resolve all conflicts, and try to suggest how the conflicts could be resolved. In this case, our commits can be automatically merged, so add in a simple message, as shown below.
Once you are ready, click “Create pull request” and your request will be made.
Dealing with a pull request
You can see all pull requests by clicking on the “Pull Request” icon on the right of the screen, e.g.
Clicking on this pull request will open up a forum that you can use to discuss this request with other developers. If the pull request can be automatically merged, then you can click “Merge Pull Request” to automatically merge and close the pull request. Alternatively, clicking on “view command line instructions” will show the commands you need to run to merge manually.
We are going to merge manually, using the “cloned” repository to simulate a different user.
Change into the “cloned” repository
cd
cd tmpdir/versioned_dir
Use git status
to ensure that your working directory is clean and you are on the master
branch. Run git pull
to make sure you have pulled in the latest changes.
Now, we will bring in the changes from the cloud new-feature
branch.
git fetch origin
git checkout -b new-feature origin/new-feature
This pulls in all information from origin
, and then checks out the new-feature
branch, ensuring that it tracks the origin/new-feature
branch. If you now type git branch
you should see that you have switched to the new-feature
branch.
Next, we need to merge in all of the changes from master
to new-feature
.
git merge master
If there are any conflicts, you will need to resolve them, and you will then need to commit the changes using git commit -a
and git push
(in our case, the merge from master
has not changed anything, so git commit -a
and git push
are not necessary).
Now, switch back to the master
branch, using
git checkout master
We now merge new-feature
into master
, using
git merge --no-ff new-feature
The --no-ff
option is necessary and will ensure that an automatic commit will be requested. This will open up your text editor to let you write this commit message. You should say that you are merging in response to a pull request. This will now merge every change from new-feature
into master
, and you should see something like
Merge made by the 'recursive' strategy.
README.md | 7 +++++++
1 file changed, 7 insertions(+)
Finally, push to origin
the changes that you have made to your local copy of master
git push origin master
You should see something like
Counting objects: 1, done.
Writing objects: 100% (1/1), 259 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/chryswoods/versioned_dir.git
d1c8fc0..a85c01c master -> master
You will notice on github.com that GitHub has automatically recognised that you have merged the pull request, and the page should have automatically updated to look something like below
At this point the pull request has been closed. As the branch has now been merged, it can be deleted. Click “Delete Branch” to remove this temporary branch from your GitHub cloud repository.
If you return to the main GitHub page for your repository, you should see that the changes in new-feature
have been merged, and that new-feature
has disappeared from the list of visible branches, e.g.
Ideal Workflow
The best way to use Git and GitHub for a multi-user project is to make a lot of use of temporary branches and pull requests.
Whenever you want to implement a new feature, you should create a new temporary branch. Give this branch a name that gives some idea of who you are, and what feature you are implementing. Then, make the changes, committing and pushing regularly.
When you have finished, do what you can to merge as much as possible from master
into your new feature branch. As far as possible, you want your pull request to be automatically mergeable.
Then, issue a pull request, giving a useful message to other developers to encourage them to put effort into merging your changes. Participate in the resulting discussion on the pull request forum, and help merge in all of the code.
Once ready, merge the pull request with the co-operation and help of other developers (and normally the blessing of the person/group that manages master
). Once merged, close the pull request and delete the temporary branch.
While Git cannot help with the social problems of working on a multi-person project, the above process of “branch and pull-request” makes it as painless as possible, particularly if you have good communication in the pull request forum.