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.

  • Git submodule foreach – updating many submodules at once

    If you have a repository with many submodules, it’s easy to update them all at once.

    For example: I have my vim dotfiles in a Git repository. Not only does this make it easier for me to keep my vim setup the same across multiple machines, but also lets me add other bundles as submodules which makes it easy to update the bundles and propagate changes.

    Once in a while I go into the repository and run:

    git submodule foreach 'git pull || :'
    

    The foreach command evaluates a shell command in each of the submodules. In this case git pull. The || : (in bash this is ‘or true’) stops the foreach command from terminating because of a non-zero return from the shell command.

    Or, you could avoid the zero return problem by echoing the return value:

    git submodule foreach 'echo `git pull`'
    

    This is just one use of foreach. Since I don’t actually develop the submodules, I can keep the repository tidy by running:

    git submodule foreach 'echo `git gc --aggressive`'
    

    Tagged: git submodule repository pull

    Posted on March 5, 2011 with 19 notes ()

  • Three ways of excluding files.

    Almost every git user knows about adding a .gitignore file to root of the project to control the visibility of files and folders. Because this file is in the repository; this configuration also applies to remote repositories of the project. But it’s not the only way. I’m going to tell you how to get Git to ignore files on a per computer and per repository basis. These could be better choices in some circumstances.

    There are three types of exclude files; from highest to lowest order of precedence they are:

    Per Project: .gitignore file in the repository

    This is the usual way of adding an ignore file. Call it .gitignore and save it to the root of your project to apply to all the files (you can add different .gitignore files in subdirectories where they have lesser scope). It is a part of the repository, so it will need to be git-added and committed for each change. This is useful for repositories that are passed around with others who may not have a per computer exclude file, or when there are project specific files that need to be taken into account.

    Even easier if you have per computer file, you can copy it straight in to your project with a simple cp ~/.gitignore .gitignore and edit to handle your specific requirements.

    Per Repository: in .git/info/excludes

    You can exclude files on a per repository basis by editing the .git/info/excludes file in your repository. (Why it takes it from this location rather than .git/config I don’t know: add it to the list of git annoyances). These exclusions (or inclusions, you can override the higher level exclusions by prepending ! to lines that you want to include) are not shared with the working directory, so they only apply to that particular repository, and are not shared with any remotes. This is useful when you have particular requirements because of your workflow or machine setup.

    Per Computer: through settings in ~/.gitconfig

    There should already be a .gitconfig file in your home directory. This is where the global setting for your git installation are stored; such as the user’s name and email address. Within this you can set a path to an excludes file that will apply to all git repositories on the computer in the same way as the name and email defined in this file apply to all repositories.

    For example: Most of what I do is in Xcode so I have the following ~/.gitignore file

    # Mac OS X
    *.DS_Store
    
    # Xcode
    *.pbxuser
    *.mode1v3
    *.mode2v3
    *.perspectivev3
    *.xcuserstate
    project.xcworkspace/
    xcuserdata/
    
    # Generated files
    build/
    *.[oa]
    *.pyc
    
    # Backup files
    *~.nib
    

    And in my .gitconfig file under the [core] section I’ve added the path to this file for the excludesfile key.

    [core]
        excludesfile = ~/.gitignore

    Now I have a standard set of ignores that apply to all my git repositories on this machine without me having to add a specific .gitignore file to each one. This is probably most useful if you create a lot of repositories for yourself, but I recommend it to everyone. It’s lowest on the precedence scale and provides a neat catch-all.

    Summary

    Most of the time the first solution is quite adequate, having exclusions within a repository that is likely to have a public face is probably the most effective way of managing file visibility. But, as with most of Git, there are ways of handling edge cases. You just need to know that they are there.

    REFERENCE

    The gitignore man page.

    Note

    This may seem familiar, I’ve taken it from a post on my personal site.

    Tagged: git ignore exclude global local remote repository

    Posted on April 13, 2010 with 35 notes ()

  • Adding an empty directory to a commit.

    I believe there are cases where a directory needs to exist in a repository but it’s empty. Either because it will be written into at a later stage, or because the contents have been ignored.

    If you remember, Git tracks content, not files. Because there is no content, the directory is not tracked, even if you add it. This might cause problems. The work-around is simple. Just create an empty file in the directory (call it something like .empty, use a dotfile so that it won’t necessarily show up in file lists) and git add this to the repository. Because there is something in the directory, it will now be tracked.

    A little inelegant, maybe. But not as inelegant as having code that depends on the existence of a directory.

    Tagged: day19 directory empty git repository track

    Posted on April 11, 2010 with 5 notes ()

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