Git » History » Revision 3
Revision 2 (Adam Sutton, 2013-02-01 11:50) → Revision 3/10 (Adam Sutton, 2013-02-01 12:20)
h1. Git for TVH Dummies
As I get quite a few people asking me what the right way to work with git is, in particular in relation to submitting patches upstream, I thought it might be a good idea to write a quick wiki entry to help with some common tasks.
I'm also fairly new to git, I'd only touched it occasionally before getting involved in Tvheadend, but I've now been using it solidly for about a year. So while I'm by no means an expert, I'll at least point out some of the things I've learnt over that year.
h2. Github
Tvheadend hosts its primary repository on "github":https://github.com, this is a useful community site as not only does it provide basic git hosting but also some useful tools for managing the project. This includes the ability for users to create public forks, submit Pull Requests (PRs) and to comment on commits and other things.
The main project page can be found at https://github.com/tvheadend/tvheadend.
If you don't intend to actively contribute to the development you can simply clone the repository for the purpose of [[Building]] and the rest of this article is probably not relevant. However should you later decide you do want to push stuff back upstream then there are some useful hints below.
h2. Forking
The first thing you should do if you intend to actively develop and push features/fixes upstream is to create a public fork on "github":https://github.com (you can use other services, but it won't fit as well with the general project workflow and the [[Team]] may get grumpy!).
To create the fork simply click on the fork icon: !fork.png!
This will create a new personal fork on github, which will allow you to publish your own changes etc.
You will also need to add an SSH key to your account to be able to push changes to your fork. If you're unsure how to do this please visit the "github ssh help page":https://help.github.com/articles/generating-ssh-keys.
Once that is all done you should create a clone of your repository using the SSH access URL (this will give you push access):
!clone.png!
<pre>
git clone [email protected]:USERNAME/tvheadend.git
</pre>
h3. Fixing upstream clone
If you have already cloned the upstream (tvheadend/tvheadend.git) repository and now want to create you're own github fork, while still retaining your local repository (possibly with commits you've already made). First create the github fork as above, and instead of cloning that repository do the following within your existing local repository:
<pre>
git remote rename origin upstream
git remote add origin SSH_URL
git fetch origin
git branch --set-upstream master origin/master
</pre>
h2. Branches
It is highly recommended that when you're looking to make changes, especially those you eventually want to submit upstream, that you create a branch.
There are several ways to create branches within git, but the two most common that I use are:
<pre>
git branch BRANCHNAME
</pre>
and
<pre>
git checkout -b BRANCHNAME
</pre>
This will both create a new branch (called BRANCHNAME) from the currently HEAD. The only difference is the second command will also switch you to the newly created branch.
If at any time you want to checkout another (existing) branch, do the following:
<pre>
git checkout BRANCHNAME
</pre>
Finally should you want to create a local branch from an existing branch on another fork (such as the upstream tvheadend fork), you can do the following:
<pre>
git checkout -t REMOTENAME/BRANCHNAME
</pre>
This will create a new local branch, with the same name as the remote branch, set it up to track (this means git will among other things tell you the status of your branch relative to the tracked version) and switch to the new branch.
To publish this branch to your public repository, as always with git there are a number of different ways of doing this. However for simplicity I usually do the following:
<pre>
git push -u origin HEAD
</pre>
This will publish a new branch to your public repository, using the same name as the local branch. It will also set the local branch to track the remote one.
If you need to send subsequent updates, you can simply do the following:
<pre>
git push
</pre>
Note: Both of the above commands assume that you've already checked out the branch you want to publish.
h2. Pull Requests
Eventually you've hopefully created some wonderful new feature or fixed some horrendous bug and you want to share that with the rest of the project. The way this is done is by creating a Pull Request (PR for short).
A PR is basically a way of saying "hey I've got this cool code, please include it upstream". The development team (or whoever you submit the PR to) can then review your commit, will possibly make comments and ask for changes. And hopefully, if the change is a good one, it will eventually be pulled into the upstream fork and the rest of the world will benefit.
To begin the PR process, you should hopefully already have a branch that you intend to submit. If not create one now, it'll save you hassle later. The reason being that when you submit a PR you're basically saying pull from this branch, so any commits you add to that branch will automatically be added to the PR. And then make sure this has been published to your public fork.
If you visit your github project page, you should now see something like this:
!newbranch.png!
Click the "Pull Request" button, fill in the form and hit "Send Pull Request". And that's it, code submitted and ready for review.
h3. Rebasing
One thing that you should really think about doing before submitting a PR is to clean up the branch, if you don't you'll mostly likely be asked to when you do submit it.
The bare minimum you should look to do is rebase your commits on top of the current upstream master. This ensures that the code will cleanly merge and that no conflicts exist. It will also make the commit history cleaner and easier to review.
To do the rebasing, run the following command:
<pre>
git rebase upstream/master
</pre>
You could also squash some commits, this can be especially useful if the branch is littered with lots of commits as you to and fro your way to a solution (mine certainly are usually like that!). The way I usually do this is to use the interactive rebase tool:
<pre>
git rebase -i upstream/master
</pre>
This will present you with a list of your commits, something like:
<pre>
pick 46f2170 update readme date
# Rebase 2e25766..46f2170 onto 2e25766
# Some helpful info...
</pre>
From here you can reorder commits, by simply moving the lines around, squash commits (change pick to fixup or f), remove commits completely (delete the line) or simply change the commit message (change pick to reword or r). Save the file and git will start to apply the changes.
If the process encounters problems, such as conflicts, then you will need to intervene. The conflicting files will need to be edited to resolve the conflicts, then added back into the commit and finally the rebase continued:
<pre>
edit FILE(s) - manually resolve conflicts
git add FILE(s)
git rebase --continue
</pre>
How you go about resolving conflicts is down to you.
It's also worth noting that when you rebase things you're changing history and this may cause problems when trying to push to a remote (if the commits you've modified were already upstream). To resolve this you may be forced to forcefully push the updates, using:
<pre>
git push -f
</pre>
h3. Changes
Should you want to make changes, or be asked by the upstream [[Team]], then you will need to first make these in the local copy of the branch used for the PR. You then simply publish those changes upstream:
<pre>
git push
</pre>
As I get quite a few people asking me what the right way to work with git is, in particular in relation to submitting patches upstream, I thought it might be a good idea to write a quick wiki entry to help with some common tasks.
I'm also fairly new to git, I'd only touched it occasionally before getting involved in Tvheadend, but I've now been using it solidly for about a year. So while I'm by no means an expert, I'll at least point out some of the things I've learnt over that year.
h2. Github
Tvheadend hosts its primary repository on "github":https://github.com, this is a useful community site as not only does it provide basic git hosting but also some useful tools for managing the project. This includes the ability for users to create public forks, submit Pull Requests (PRs) and to comment on commits and other things.
The main project page can be found at https://github.com/tvheadend/tvheadend.
If you don't intend to actively contribute to the development you can simply clone the repository for the purpose of [[Building]] and the rest of this article is probably not relevant. However should you later decide you do want to push stuff back upstream then there are some useful hints below.
h2. Forking
The first thing you should do if you intend to actively develop and push features/fixes upstream is to create a public fork on "github":https://github.com (you can use other services, but it won't fit as well with the general project workflow and the [[Team]] may get grumpy!).
To create the fork simply click on the fork icon: !fork.png!
This will create a new personal fork on github, which will allow you to publish your own changes etc.
You will also need to add an SSH key to your account to be able to push changes to your fork. If you're unsure how to do this please visit the "github ssh help page":https://help.github.com/articles/generating-ssh-keys.
Once that is all done you should create a clone of your repository using the SSH access URL (this will give you push access):
!clone.png!
<pre>
git clone [email protected]:USERNAME/tvheadend.git
</pre>
h3. Fixing upstream clone
If you have already cloned the upstream (tvheadend/tvheadend.git) repository and now want to create you're own github fork, while still retaining your local repository (possibly with commits you've already made). First create the github fork as above, and instead of cloning that repository do the following within your existing local repository:
<pre>
git remote rename origin upstream
git remote add origin SSH_URL
git fetch origin
git branch --set-upstream master origin/master
</pre>
h2. Branches
It is highly recommended that when you're looking to make changes, especially those you eventually want to submit upstream, that you create a branch.
There are several ways to create branches within git, but the two most common that I use are:
<pre>
git branch BRANCHNAME
</pre>
and
<pre>
git checkout -b BRANCHNAME
</pre>
This will both create a new branch (called BRANCHNAME) from the currently HEAD. The only difference is the second command will also switch you to the newly created branch.
If at any time you want to checkout another (existing) branch, do the following:
<pre>
git checkout BRANCHNAME
</pre>
Finally should you want to create a local branch from an existing branch on another fork (such as the upstream tvheadend fork), you can do the following:
<pre>
git checkout -t REMOTENAME/BRANCHNAME
</pre>
This will create a new local branch, with the same name as the remote branch, set it up to track (this means git will among other things tell you the status of your branch relative to the tracked version) and switch to the new branch.
To publish this branch to your public repository, as always with git there are a number of different ways of doing this. However for simplicity I usually do the following:
<pre>
git push -u origin HEAD
</pre>
This will publish a new branch to your public repository, using the same name as the local branch. It will also set the local branch to track the remote one.
If you need to send subsequent updates, you can simply do the following:
<pre>
git push
</pre>
Note: Both of the above commands assume that you've already checked out the branch you want to publish.
h2. Pull Requests
Eventually you've hopefully created some wonderful new feature or fixed some horrendous bug and you want to share that with the rest of the project. The way this is done is by creating a Pull Request (PR for short).
A PR is basically a way of saying "hey I've got this cool code, please include it upstream". The development team (or whoever you submit the PR to) can then review your commit, will possibly make comments and ask for changes. And hopefully, if the change is a good one, it will eventually be pulled into the upstream fork and the rest of the world will benefit.
To begin the PR process, you should hopefully already have a branch that you intend to submit. If not create one now, it'll save you hassle later. The reason being that when you submit a PR you're basically saying pull from this branch, so any commits you add to that branch will automatically be added to the PR. And then make sure this has been published to your public fork.
If you visit your github project page, you should now see something like this:
!newbranch.png!
Click the "Pull Request" button, fill in the form and hit "Send Pull Request". And that's it, code submitted and ready for review.
h3. Rebasing
One thing that you should really think about doing before submitting a PR is to clean up the branch, if you don't you'll mostly likely be asked to when you do submit it.
The bare minimum you should look to do is rebase your commits on top of the current upstream master. This ensures that the code will cleanly merge and that no conflicts exist. It will also make the commit history cleaner and easier to review.
To do the rebasing, run the following command:
<pre>
git rebase upstream/master
</pre>
You could also squash some commits, this can be especially useful if the branch is littered with lots of commits as you to and fro your way to a solution (mine certainly are usually like that!). The way I usually do this is to use the interactive rebase tool:
<pre>
git rebase -i upstream/master
</pre>
This will present you with a list of your commits, something like:
<pre>
pick 46f2170 update readme date
# Rebase 2e25766..46f2170 onto 2e25766
# Some helpful info...
</pre>
From here you can reorder commits, by simply moving the lines around, squash commits (change pick to fixup or f), remove commits completely (delete the line) or simply change the commit message (change pick to reword or r). Save the file and git will start to apply the changes.
If the process encounters problems, such as conflicts, then you will need to intervene. The conflicting files will need to be edited to resolve the conflicts, then added back into the commit and finally the rebase continued:
<pre>
edit FILE(s) - manually resolve conflicts
git add FILE(s)
git rebase --continue
</pre>
How you go about resolving conflicts is down to you.
It's also worth noting that when you rebase things you're changing history and this may cause problems when trying to push to a remote (if the commits you've modified were already upstream). To resolve this you may be forced to forcefully push the updates, using:
<pre>
git push -f
</pre>
h3. Changes
Should you want to make changes, or be asked by the upstream [[Team]], then you will need to first make these in the local copy of the branch used for the PR. You then simply publish those changes upstream:
<pre>
git push
</pre>