Difference between revisions of "Using Git"

From Dogtag
Jump to: navigation, search
m (Rewinding Commits)
m (Developing on a Local Branch)
(4 intermediate revisions by the same user not shown)
Line 54: Line 54:
 
Now that we are in a local branch, make the necessary changes, then make sure the changes are staged for commit.
 
Now that we are in a local branch, make the necessary changes, then make sure the changes are staged for commit.
  
To stage a new file or the changes in an existing file:
+
To check the status of the changes:
  
  $ git add <file>
+
  $ git status
  
To check the status of the changes:
+
To stage the changes in a file or to add a new file:
  
  $ git status
+
  $ git add <file>
  
 
To commit the changes:
 
To commit the changes:
Line 95: Line 95:
 
  $ git rebase master
 
  $ git rebase master
  
If there's no conflict, the commands should complete immediately.
+
If there's no conflict, the commands should complete immediately. If there are conflicts, it will show the files that have conflicts.
If there are conflicts, you will need to fix the conflicts first.
+
 
 +
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 =
 
= Pushing the Local Branch to Forked Repository =
Line 144: Line 147:
 
= Squashing a Commit =
 
= Squashing a Commit =
  
To squash a commit into the previous commit (i.e. merging into a single commit) in the local branch:
+
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 reset --soft HEAD^
Line 155: Line 158:
 
  $ git reset --hard HEAD^
 
  $ git reset --hard HEAD^
  
= Working with Remote Branches =
+
= Backporting a Commit =
When you want to make changes on a remote branch, the first thing that you need to do is to create a local branch to track the remote branch.  This will work the same way that our local '''master''' branch tracks the remote '''master''' branch.
 
  
The first step is to list the remote branches.  This is done the same way as listing local branches, except we add the '''-r''' option:
+
To backport a commit into an older branch, first find the target branch:
  
 
  $ git branch -r
 
  $ git branch -r
Line 165: Line 167:
 
   origin/master
 
   origin/master
  
In this case, we are going to assume that we want to port a change that we have on our local '''master''' branch over to the remote '''DOGTAG_10_5_BRANCH''' branch.  To create our local branch, we simply checkout using the remote branch name:
+
Then checkout the branch:
  
 
  $ git checkout DOGTAG_10_5_BRANCH
 
  $ git checkout DOGTAG_10_5_BRANCH
Branch DOGTAG_10_5_BRANCH set up to track remote branch DOGTAG_10_5_BRANCH from origin.
 
Switched to a new branch 'DOGTAG_10_5_BRANCH'
 
  
If you were simply doing new development on this branch, you could just do your development work here (or create a local branch from this point to avoid merge issues). For our example here, we're going to be porting a change from the '''master''' branch.  This is done with the cherry-pick command.  Here is an example of how we would do this (along with some commit log output to help show how it works):
+
It should create a tracking branch automatically. If not, that can be done with the following command:
  
  $ git branch
+
  $ git checkout -b DOGTAG_10_5_BRANCH origin/DOGTAG_10_5_BRANCH
* DOGTAG_10_5_BRANCH
+
 
  master
+
Then cherry-pick the changes from master:
  local_branch
+
 
+
  $ git cherry-pick <commit ID>
$ git log -1
+
 
commit 8ebf890b913ffbf4cb40c09ebc9e229989303095
+
Finally, push the changes:
Author: Ade Lee <alee@redhat.com>
 
Date:  Wed Jan 4 00:08:03 2012 -0500
 
 
    BZ 771357 - sslget does not work after FEDORA-2011-17400 update, breaking FreeIPA install
 
   
 
    Modified sslget doIO() function to be able to handle small reads.
 
 
$ git checkout master
 
Switched to branch 'master'
 
Your branch is ahead of 'origin/master' by 1 commit.
 
 
$ git log -1
 
commit 5516ece394889facb511265e43a70340b19cea35
 
Author: Nathan Kinder <nkinder@redhat.com>
 
Date:  Mon Jan 16 11:50:52 2012 -0800
 
 
    Updated copyright in README file
 
   
 
    The date in the copyright of README needed to be updated.
 
 
$ git checkout DOGTAG_10_5_BRANCH
 
Switched to branch 'DOGTAG_10_5_BRANCH'
 
  $ git cherry-pick 5516ece394889facb511265e43a70340b19cea35
 
[DOGTAG_10_5_BRANCH f4e12fc] Updated copyright in README file
 
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 
$ git log -2
 
commit f4e12fc3ab173dfe43d47248f11b2f39bafd6cab
 
Author: Nathan Kinder <nkinder@redhat.com>
 
Date:  Mon Jan 16 11:50:52 2012 -0800
 
 
    Updated copyright in README file
 
   
 
    The date in the copyright of README needed to be updated.
 
 
commit 8ebf890b913ffbf4cb40c09ebc9e229989303095
 
Author: Ade Lee <alee@redhat.com>
 
Date:  Wed Jan 4 00:08:03 2012 -0500
 
 
    BZ 771357 - sslget does not work after FEDORA-2011-17400 update, breaking FreeIPA install
 
   
 
    Modified sslget doIO() function to be able to handle small reads.
 
  
You can see that we only need to provide the hash of the commit that we want to port to our branch. The end result is a committed fix on our branch.  At this point, you could do a push which would push the commit to the remote '''DOGTAG_10_5_BRANCH'''.
+
  $ git push origin DOGTAG_10_5_BRANCH
  
 
= References =
 
= References =
  
 
* [[Git]]
 
* [[Git]]

Revision as of 21:54, 13 June 2019

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

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)

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 <file>

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>
Date:   Mon Jan 16 11:50:52 2012 -0800 

    Updated copyright in README file
   
    The date in the copyright of README needed to be updated.

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
$ git cherry-pick <commit ID>

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
 origin/DOGTAG_10_5_BRANCH
 origin/DOGTAG_10_6_BRANCH
 origin/master

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 <commit ID>

Finally, push the changes:

$ git push origin DOGTAG_10_5_BRANCH

References