To make Unison ignore Git repositories, add the path pattern .git to your Unison preferences file using the ignore = Name .git directive. This tells the synchronization engine to skip all files and directories matching that name during both local and remote transfers. By configuring this exclusion rule, you prevent cluttered sync logs and avoid transferring unnecessary version control metadata between machines.
Understanding Unison Exclusion Patterns
Unison is a powerful file-synchronization tool for Unix and Windows that maintains two replicas of a directory tree. Unlike simple copy commands, Unison detects changes made on either side and synchronizes them bidirectionally. However, certain directories, such as those generated by build tools or version control systems like Git, often contain transient data that should never be synchronized. These artifacts can cause conflicts, bloat storage, or corrupt the state of your project if synced incorrectly. The core mechanism for handling these exclusions in Unison is the preference file. This configuration file allows you to define rules that dictate which files are included or ignored. When Unison starts, it reads these preferences to build a list of paths to process. If a path matches anignore rule, Unison skips it entirely, treating it as if it does not exist for the purpose of synchronization. This approach is far more efficient than manually deleting files after a sync or relying on external scripts to filter results.
For Git specifically, the .git directory contains the entire history, object database, and configuration for a repository. Syncing this data across multiple machines is rarely useful because each machine usually has its own unique set of commits, branches, and hooks. Furthermore, Git handles its own distributed nature; attempting to force-sync the internal state via Unison can lead to inconsistent states where one machine's index disagrees with another's working tree. Therefore, excluding .git is a standard best practice for developers using Unison alongside Git.
Configuring the Preferences File
To implement this exclusion, you need to edit or create a preferences file for your specific synchronization setup. Unison supports both command-line arguments and a dedicated preferences file (typically named.unison in your home directory or specified explicitly). Using a preferences file is recommended for complex setups because it persists settings across sessions.
Create a file named .unison in your home directory if it does not already exist. Open this file in any text editor. You will need to add the following line to the configuration:
ignore = Name .git
This single line instructs Unison to ignore any file or directory named exactly .git at any depth within the synchronized trees. The Name keyword specifies that the match is based on the filename rather than the full path. This ensures that even nested .git folders in submodules are excluded. If you are using Unison from the command line, you can achieve the same result by adding the flag -ignore Name .git to your sync command.
It is important to note that Unison processes these rules in order. If you have other ignore rules, place this one appropriately. Typically, broad ignores come first, followed by specific exceptions. Since we want to ignore all .git directories regardless of location, placing it early in the file is safe and clear. After saving the file, your next Unison run will automatically respect this new rule.
Verifying the Configuration
Once you have added the ignore rule, it is prudent to verify that Unison is behaving as expected. You can do this by running Unison in preview mode without actually performing the synchronization. This allows you to see what changes would be made without altering your files. Use the-preview flag when launching Unison.
unison -preview /path/to/local/dir ssh://remote/path/to/remote/dir
In the output, look for lines indicating skipped files. You should see messages stating that Unison is ignoring the .git directories. If you still see .git entries being processed, check your preferences file for syntax errors. Common mistakes include typos in the ignore keyword or incorrect spacing. Ensure there are no leading spaces before the ignore directive unless you are indenting under a specific profile block.
If you are syncing large projects, verifying this step saves time by preventing unnecessary network traffic and disk I/O. It also helps confirm that your configuration is robust against future changes in your project structure. For example, if you add new submodules, their .git directories will also be automatically ignored thanks to the recursive nature of the Name matcher.
Handling Related Version Control Artifacts
While.git is the primary target, other version control systems or build artifacts might also need exclusion. If you use Mercurial, you might also want to ignore .hg. Similarly, compiled binaries or IDE-specific folders like .idea or .vscode are often excluded to keep the sync clean. You can add multiple ignore directives to your preferences file.
ignore = Name .git
ignore = Name .hg
ignore = Name *.o
ignore = Name .DS_Store
Each line adds a new rule. This modular approach allows you to tailor the synchronization behavior precisely to your workflow. It is worth noting that some IDE configurations might depend on specific files being present locally. Always ensure that excluding a directory does not break your development environment. In most cases, however, keeping the source code synced while ignoring metadata is the ideal balance between collaboration and efficiency.
For more advanced Git management strategies, such as restructuring projects or handling rebase operations, consider reviewing our guide on [restructuring your git project](/news/1401014/restructure-git-project) to maintain a clean history independent of your sync layer.
Frequently Asked Questions
Does Unison delete .git directories on the destination?
No, Unison will not delete .git directories on the destination if they are marked as ignored. Ignored paths are treated as if they do not exist in the source, so Unison never attempts to modify, update, or remove them on the other end. This ensures that existing version control structures remain intact.
Can I ignore .git only for specific subdirectories?
Yes, you can specify relative paths in your ignore rules. Instead of just Name .git, you can use Path subdir/.git to target a specific folder. This provides granular control over which parts of your project tree are affected by the exclusion rule.
What happens if I accidentally sync .git data?
If you sync .git data, you may encounter conflicts where the index or lock files differ between machines. This can lead to "index mismatch" errors in Git. Running a git gc or clearing the cache might be necessary to resolve inconsistencies caused by unsolicited updates to the repository internals.
How do I exclude files based on extension instead of name?
You can use the End keyword in your preferences file. For example, ignore = End .log will exclude all files ending with the .log extension. This is useful for excluding temporary logs or backup files that are not tied to a specific directory name.
Is it safe to ignore .git in shared hosting environments?
Yes, it is generally safe and recommended. Shared hosting typically requires only the web-accessible files to be present. The .git directory contains sensitive configuration and history that should not be publicly accessible. Excluding it prevents accidental exposure of your codebase history.