This page is intended to provide extra information about some of git's features, as well as expose and document others. While they are not explicitly necessary to know when using git, they can be helpful when using git or trying to accomplish effective version control.
Unlike the Tips and Tricks pages from the other tutorials, this page only requires that you have read and understood the concepts in chapter 1.
There may come a time during the life of your repository that you find that you have reached a specific milestone, such as a version release, a specific deadline, or perhaps a stable feature set. At this point, you may want to leave some sort of marker on the history so you can come back to it if need be. Granted, you could just revert back to the commit hash at this point, but wouldn't it be difficult to have to remember even just the first 7 characters of the commit hash forever?
Luckily, git has a feature for just this situation, called a tag.
When you make a tag, you can effectively label a specific commit with an arbitrary name, such as v1.0
, or v0.2.3-alpha
.
This allows you to quickly grab the code from that point in history wiithout having to remember the commit hash.
In a sense, tagging is a little like branching. You create another reference in the repository, which points to a specific commit, however, tags do not have history. You cannot develop on a tag the way you can on a branch.
To create a new tag from the current HEAD
on the commandline, you can just do the following:
git tag -a <tag-name>
where tag-name
is what you wish to name the tag. Or, if you want to make a tag from a specific branch or commit, you can do this like you would when you make a branch:
git tag -a <tag-name> <source>
With regards to naming, a tag's name should be a version number (with an optional v
prefix), and follow a sensible versioning system.
When you execute this command, it will bring up a text editor for you to leave a message. This is a good place to leave some release notes about your software at this particular point in development.
Unlike commit messages, tag messages don't have a title — only a body.
When you're done, save the file. This will save the tag message, and git will add the tag to its list of references.
In a GUI, where this function is found can vary. In EGit, it is located under Advanced
in the Team
menu.
In TortoiseGit, this function is called Create Tag
and is located in the primary TortoiseGit menu.
Although you really shouldn't find yourself in a situation where you need to delete a tag, this is possible as well, using the -d
switch of the git tag
command:
git tag -d <tag-name>
If you want to push a tag to the remote repository, the git push
command looks a little different.
git push --tags origin
This command will push all of the tags to origin
. Because tags generally don't change, this really just pushes new tags to the remote.
If you use a GUI, the normal push process should work.
No problem. Just use the tag as a source for a new branch.
git branch myCode v1.0
git checkout -b myCode v1.0
Alternatively, if you need to reset a branch to the state of the tag, and the tag's commit is in that branch's history, then you can use the tag with your reset
command:
git reset --hard v1.0
Even though merging is a wonderful thing, it will always merge everything from the two branches' most recent common ancestor to their present HEAD
s.
This is sufficient in most cases, but sometimes you may find yourself needing to merge just a few specific commits from one branch into another.
Because of the nature of merging, this is not really possible by doing a really complex merge. You have to do some of the heavy lifting yourself.
The process for this, however, is simple. The first step is to get a diff across all of the commits you want and save it to a file:
git diff <first-commit> <last-commit> > mydiff.patch
This command will generate an overarching commit for every commit made from first-commit
to last-commit
and store it in a text file called mydiff.patch
.
The next step from here is to take the patch and apply it to the proper branch (while being sure to keep track of mydiff.patch
).
So, switch to the branch you want to apply the patch to, and then use the git apply
command to apply the diff to the working tree.
git apply mydiff.patch
git apply
Firstly, git apply works without looking at your repository's history. All it does is look at the patch file you give it and apply the changes that the patch file specifies.
Because of this, code conflicts will not occur.
This may seem like a blessing at first, but it actually means that running git apply
is like running git merge
with the --theirs
switch.
Any changes listed in the patch will always take precedence over changes that you have made in your local directory.
Secondly, git apply
is limited because it doesn't access the commit history
— if a file has changed enough so that git can't really tell what lines are supposed to go where, you may end up with some interesting results.
Finally, and partly as a function of the last point, newlines and whitespaces can screw up the patch application process often.
If this is the case, git will ask you to run the apply
command with the --ignore-whitespace
or --whitespace=nowarn
options.