365Git

  1. Search
  2. About
  3. Subscribe
  4. Archive
  5. Random

365Git

Regular small snippets and workflows for Git

My original plan of a post everyday turned out to be unrealistic, but I'll carry on posting as regularly as I can.

Find me @abizern on twitter if you have anything you'd like me to cover.

  • Signing a Git Tag

    I’ve already written about the Git Tag Object and made a passing reference to signed tags.

    Git doesn’t make any checks about whether the name and email you enter into a git config file really is you, so it’s trivial make a check-in that looks like it’s been made by someone else. But, if you have some form of GPG installed, you can cryptographically sign a tag object (not a lightweight tag) than can be verified as being created by you.

    Since a tag object references a commit, which in turn references another commit, and so on, a tag verifies a whole tree of commits. Changing any of the commits, or the tag, would mean new objects would be created that would break this tree. So by signing a tag, which points to a commit, a whole section of the code history is being validated by someone. And if you trust that person, and you trust his public key, you can verify that the tag was created by that person.

    To create a signed tag, just pass the -s flag instead of the -a flag:

    git tag -s -m"tagging version 1.0" v1.0

    This will create a signed tag object called v1.0 with the passed commit message and it will use the signing identity of the committer (if there is a key for that). The documentation for git-config states that you can set a key for user.signingkey that will be used by default to sign commits, but I’ve found that I don’t need to do this as the correct key is used based on the user.email that I am using. A prompt will come up asking you for your key’s passphrase.

    If you want to use a particular signing identity when tagging then use then use:

    git tag -u <key-id> -m"tagging version 1.0" v1.0

    Here, the -u <key-id> specifies the key to use.

    Also, as with commit messages, if you leave out the message an editor will be brought up for you to enter the tag message.

    The signed tag object is only slightly different from the unsigned tag object in that it has a PGP signature block. To verify the signature use the -v flag of the tag command

    git tag -v v1.0

    and if you have the correct public key for the user in your GPG Keychain it will let you know if the signature is valid or not.

    In my earlier post I also mentioned that a tag object does not have to point at a commit; it can point to any other git object. In this way, you can also tag individual files or trees or even other tags if you are paranoid enough to want to. But this does nothing more than putting a name to a tag, or a commit. It establishes nothing more than responsibility - not a guarantee of quality nor of the origin of the work.

    Tagged: git tag gpg signed cryptographically

    Posted on January 17, 2011 with 20 notes ()

  • Git objects: the tag

    The final object left to cover is the tag. Strangely (or not, depending on your view of Git) there are two types of tags. There are lightweight tags which are almost like branches, but here I’ll introduce the tag object.

    Tagging

    A tag is a shorthand way of naming an object, usually a commit, so it can be referred to easily. A tag object differs from a lightweight tag in that it is a complete object with an author, message, and date. It can also be cryptographically signed with GPG. Very much like a commit.

    The obvious use for tags is to mark releases. v1.0, v1.7, etc. It’s easy to check out these commits by using the memorable name rather than the sha. Using the object tag is useful here if you need to sign these milestones.

    Another use for tags is to mark points in code that you might want to go back to; such as before you embark on implementing a mad idea and just creating a separate branch isn’t enough. A tag object here is useful because you create the tag with a message explaining why you are creating the tag.

    I sometimes use tags to park dead branches. If I’ve followed a line of development that I want to shelve, I create a tag at the tip of the branch and delete the branch. That way, when I look at the state of my repository, I don’t see these dead branches listed, but I can always go back to it by creating a branch from that tag.

    Graphically:

    Simple tagging scheme

    You can create a branch based off a tag by using the normal git checkout or git branch commands:

    git branch newBranch PreCrazy will create a new branch based on the commit pointed to by PreCrazy.

    You can checkout a tag directly without creating a branch off it. But this creates a “detached head”. Usually HEAD points to a branch rather than to a commit directly, but when you check out a commit without creating a branch then HEAD points directly to a commit, and you will see a helpful message on the console to tell you what you have done. If you wish, you can always move back to a branch with git checkout because those references still exist even though HEAD has moved. You can still add commits to the repository and they will form a chain, but since they are not on a branch, they are liable to be garbage collected away at some point and deleted.

    Using a tagging scheme

    Creating a tag object.

    The simplest way to create a tag object is to create one with an inline message:

    git tag v1.0 -m"Tagging version 1.0"

    If a longer message is required use the -a flag (shorthand for creating and annotated commit) instead and the default editor will come up making it easier to create a message.

    git tag -a v1.0

    These two examples create tags at the current head commit. But you can tag previous commits simply by passing in the sha of the commit

    git tag -a v2.0 e34f77c

    You can create tag objects for more than just commits, you can tag blobs and trees as well, just by passing in the sha of the blob or the tree. Why anyone would want to do this is beyond me. It isn’t as if you can check out a single file based on a tagged blob, although you could reference it’s contents. Maybe it can be used to cryptographically sign a file or a tree as coming from a particular source so verify it’s integrity.

    Listing tag objects

    A simple git tag will list all the tags in the repository. If you mostly use version tagging, then the names will be self explanatory. You can further examine tags using git cat-file -p <tagname> which I prefer to git show <tagname> which also shows a diff. Graphical tools such as Gitk show tagged commits, but not tagged files or trees, so it’s worth using the command line options sometimes to see if there is anything else lurking.

    Summary

    A tag is a convenient way of assigning a shorthand name to a commit and marking significant points. A tag object allows for extra information to be added to this shorthand name, such as committer information, a message, or an electronic signature. Tag objects can also be assigned to git objects other than commits, such as blobs and trees.

    There is more that I can write about tags and the other objects. It helps me a great deal when using git to know about how these building blocks combine to create a repository. Even though there are hundreds of ways of sending commands to git, they mostly just work on these objects. Keeping that in mind makes using Git less complex.

    Tagged: Fundamentals cat-file day13 git object tag git-show

    Posted on April 5, 2010 with 3 notes ()

Field Notes Theme. Designed by Manasto Jones. Powered by Tumblr.