Assorted git-related scripts and tools
- Git (duh!). Tested in v2.17.1 and prior versions since 2010
- Python (for
git-restore-mtime
). Tested in Python 3.6, also works in Python 3.1+ - Bash (for all other tools). Tested in Bash 4, some may work in Bash 3 or even
sh
Bash and Python are already installed by default in virtually all GNU/Linux distros. And you probably already have Git if you are interested in these tools. If needed, the command to install dependencies for Debian-like distros (like Ubuntu/Mint) is:
sudo apt install bash python3 git
On recent Debian, Ubuntu 16.04+, Mint and their derivatives, most tools are in the repositories as git-restore-mtime
:
sudo apt install git-restore-mtime
On Fedora 27+ and EPEL 6+, as root:
yum install git-tools
Gentoo Testing, also as root:
emerge dev-vcs/git-tools
To manually install and run from the repository, just clone the repository and add the installation directory to your $PATH
cd ~/some/dir
git clone https://github.com/MestreLion/git-tools.git
echo 'PATH=$PATH:~/some/dir/git-tools' >> ~/.profile # or ~/.bashrc
If you installed using your operating system package manager, or if you added the cloned repository to your $PATH
, you can simply run the tools as if they were regular git
subcommands! For example:
git restore-mtime --test
The magic? Git considers any executable named git-*
in either /usr/lib/git-core
or in $PATH
to be a subcommand! It also integrates with man
, triggering the manual pages if they're installed, such as when installing using your package manager:
git restore-mtime --help
git help strip-merge
In case the manual pages are not installed in the system, such as when running from the cloned repository, you can still read the built-in help by directly invoking the tool:
git-clone-subset --help
For the packaged versions, use your repository tools such as apt
, yum
, emerge
.
For the manual installation, just delete the directory and remove it from your $PATH
.
rm -rf ~/some/dir/git-tools
sed -i '/git-tools/d' ~/.profile
This is a brief description of the tools. For more detailed instructions, see --help
of each tool.
Batch renames branches with a matching prefix to another prefix
Examples:
$ git-rename-branches bug bugfix
bug/128 -> bugfix/128
bug_test -> bugfix_test
$ git-rename-branches ma backup/ma
master -> backup/master
main -> backup/main
Clones a subset of a git repository
Uses git clone
and git filter-branch
to remove from the clone all but the requested files, along with their associated commit history.
Clones a repository
into a destination
directory and runs on the clone git filter-branch --prune-empty --tree-filter 'git rm ...' -- --all
to prune from history all files except the ones matching a pattern
, effectively creating a clone with a subset of files (and history) of the original repository.
Useful for creating a new repository out of a set of files from another repository, migrating (only) their associated history. Very similar to what git filter-branch --subdirectory-filter
does, but for a file pattern instead of just a single directory.
Recursively list repos with uncommitted changes
Recursively finds all git repositories in the given directory(es), runs git status
on them, and prints the location of repositories with uncommitted changes. The tool I definitely use the most.
Resolve rebase conflicts and failed cherry-picks by favoring 'theirs' version
When using git rebase
, conflicts are usually wanted to be resolved by favoring the working branch
version (the branch being rebased, 'theirs' side in a rebase), instead of the upstream
version (the base branch, 'ours' side). But git rebase --strategy -X theirs
is only available from git 1.7.3. For older versions, git-rebase-theirs
is the solution. Despite the name, it's also useful for fixing failed cherry-picks
Restore original modification time of files based on the date of the most recent commit that modified them
Probably the most popular and useful tool, and the reason this repository was packaged into distros.
Git, unlike other version control systems, does not preserve the original timestamp of committed files. Whenever repositories are cloned, or branches/files are checked out, file timestamps are reset to the current date. While this behavior has its justifications (notably when using make
to compile software), sometimes it is desirable to restore the original modification date of a file (for example, when generating release tarballs). As git does not provide any way to do that, git-restore-mtime
tries to workaround this limitation.
For more information and background, see http://stackoverflow.com/a/13284229/624066
For TravisCI users, simply add this setting to .travis.yml
so it clones the full repository history:
git:
depth: false
Similarly, when using Github Actions, make sure to include fetch-depth: 0
in your checkout workflow, as described in its documentation:
- uses: actions/checkout@v2
with:
fetch-depth: 0
A git-merge
wrapper that delete files on a "foreign" branch before merging
Answer for "How to set up a git driver to ignore a folder on merge?", see http://stackoverflow.com/questions/3111515
Example:
$ git checkout master
$ git-strip-merge design photoshop/*.psd
Patches are welcome! Fork, hack, request pull!
If you find a bug or have any enhancement request, please open a new issue
Rodrigo Silva (MestreLion) [email protected]
Copyright (C) 2012 Rodrigo Silva (MestreLion) <[email protected]>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.