Overview#
This page shows how to accomplish some common development procedures using Git. There are usually multiple ways to accomplish the same thing in Git, so keep in mind that the steps below are only one way of doing things. There may be other shortcuts or different ways of doing things that you prefer.
Creating a Local Repository#
First, create a clone of the upstream repository on the local machine. There are two ways to do this depending on the purpose of the local repository.
If the repository is to be used for read-only access (e.g. for builds, for pull requests), it can be cloned anonymously using the HTTPS URL, for example:
$ git clone ``\ ```https://github.com/dogtagpki/pki.git
<dogtagpki/pki.git>`__
If the repository is to be used for write access (e.g. pushing commits directly, creating upstream branches/tags), it should be cloned with authentication using the SSH URL, for example;
$ git clone git@github.com:dogtagpki/pki.git
Verify with the following commnad:
$ git remote -v
origin git@github.com:dogtagpki/pki.git (fetch)
origin git@github.com:dogtagpki/pki.git (push)
Forking Upstream Repository#
For development it’s recommended to create a fork of the upstream repository for submitting a GitHub Pull Request and/or to run Travis CI.
Once the fork has been created, add it into the local repository, for example:
$ cd pki
$ git remote add edewata git@github.com:edewata/pki.git
$ git fetch
Verify with the following command:
$ git remote -v
origin git@github.com:dogtagpki/pki.git (fetch)
origin git@github.com:dogtagpki/pki.git (push)
edewata git@github.com:edewata/pki.git (fetch)
edewata git@github.com:edewata/pki.git (push)
Synchronizing Forked Repository#
After sometime the upstream repository may have additional changes that do not exist in the forked repository. To synchronize these changes, pull the changes into a local branch that tracks the upstream branch (e.g. master):
$ git checkout master
$ git pull
then push the local branch into the forked repository:
$ git push edewata master
If the upstream and forked branches have diverged somehow, the push may fail. To resolve it, simply force push the changes:
$ git push edewata master --force
Developing on a Local Branch#
The preferred way of doing development is to do your work on a local branch. This makes it easy to isolate fixes you are working on from each other. It also helps to prevent merge issues when you are ready to push your changes up to the remote repository. The following example shows the commands a developer would use to fix a bug on a local branch.
The first step is to create a local branch. You should name your branch something descriptive, such as the bug number you are working on, or the name of the feature you are developing. Here is an example of creating a new local branch from master:
$ git checkout master
$ git checkout -b local_branch
Now that we are in a local branch, make the necessary changes, then make sure the changes are staged for commit.
To check the status of the changes:
$ git status
To stage the changes in a file or to add a new file:
``$ git add ``
To commit the changes:
$ git commit
If you want to revise the commit, make the necessary changes, stage the changes again as above, then amend the commit:
$ git commit --amend
When you run the commit command, you will have to fill in the commit message for your commit. The format should be a one-line summary of the fix (including the applicable bug or ticket number if appropriate), followed by a blank line and a more complete description of the change. Now that our change is commited to our local branch, we can look at the commit history to confirm that our commit is there. We’ll also check the status of the tree to show that git considers the tree to be up to date.
$ git log
commit 535cf2d38b876ac784bd3449dea885b9da4b1c3c
Author: Nathan Kinder <nkinder@redhat.com>
Rebasing the Local Branch#
Sometimes the upstream master branch may have newer changes so your local branch may need to be rebased.
To rebase the local branch, pull the latest from master with the following commands:
$ git checkout master
$ git pull
Then go back to the local branch and rebase it against master:
$ git checkout local_branch
$ git rebase master
If there’s no conflict, the commands should complete immediately. If there are conflicts, it will show the files that have conflicts.
You will need to fix the conflict, stage the changes, then resume the rebase with this command:
$ git rebase --continue
Pushing the Local Branch to Forked Repository#
To push the local branch to the forked repository, specify the name of the repository and the branch:
$ git push edewata local_branch
If you created additional commits into the local branch, you can simply push again. However, if you amended any of the commits, you may need to push with force:
$ git push edewata local_branch --force
If Travis CI is configured in the forked repository, the push will trigger the CI automatically.
Creating a Pull Request#
Once the changes are pushed from the local branch to the forked repository, you can submit a GitHub Pull Request.
After the pull request is merged, refresh the master branch with the following command:
$ git checkout master
$ git pull
The changes should appear in the master branch.
Pushing Directly to Upstream Repository#
Note: This should only be done for patches that do not need a review. It’s always recommended to push the patches to the forked repository first to make sure it passes the CI.
There are several ways to merge the changes from the local branch into master.
If the local branch has been rebased against master, fast-forward the master branch to match the local branch:
$ git checkout master
$ git rebase local_branch
If the local branch has not been rebased againt master, cherry-pick each change into master:
$ git checkout master
Once the changes are in master, push the changes to upstream with the following command:
$ git push origin master
Squashing a Commit#
To squash a commit into the previous commit (i.e. merging them into a single commit) in the local branch:
$ git reset --soft HEAD^
$ git commit --amend
Removing a Commit#
To completely remove a commit from the local branch:
$ git reset --hard HEAD^
Backporting a Commit#
To backport a commit into an older branch, first find the target branch:
$ git branch -r
Then checkout the branch:
$ git checkout DOGTAG_10_5_BRANCH
It should create a tracking branch automatically. If not, that can be done with the following command:
$ git checkout -b DOGTAG_10_5_BRANCH origin/DOGTAG_10_5_BRANCH
Then cherry-pick the changes from master:
``$ git cherry-pick ``
Finally, push the changes:
$ git push origin DOGTAG_10_5_BRANCH