Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

(heart) git git.  No, seriously...  I've also used several git clients over my short lifetime, my current favourite is the awesome and beautiful (and beautifully cross-platform) gitkraken tig (ncurses git client)  - although if I had to choose a gui git client it would definitely be gitkraken.

Info

Full disclosure: I am the AUR (Arch Linux User Repository) package maintainer for gitkraken (standalone version for air-gapped networks and labs).

However, sometimes I need to do stuff that's just easier in git bashon the command line.  Below are several of these commands that I always seem to forget (dang you nice git client - making me forget my terminal roots...).

Table of Contents
maxLevel2
exclude(References|Related\sarticles)

git reset back to a previous commit

Sometimes you might want to take a local branch back to a previous commit (or state... like in between several amend commits) without actually reverting commits.

...

Code Block
themeEmacs
git reset --hard HEAD

Reset specific file to previous commit version

From time to time you may need/want to reset a specific file to a version in a previous commit.  What you essentially want to do is "checkout" the file from said commit:

Code Block
languagebash
themeEmacs
git checkout <COMMIT-HASH> -- path/file

For example, suppose I want to check reset the current file found in the path (relative to the git root foler) "i3/config", I would do:

Code Block
languagebash
themeEmacs
git checkout 3b5e3ff7ab0c3d61984532950a1c7acfe3f9efa6 -- i3/config

where 3b5e3ff7ab0c3d61984532950a1c7acfe3f9efa6 is the commit hash (you can also use the "short" hash 3b5e3ff).

Create orphan branch

In some instances you might need/want to create a branch which is not based on another branch.  This is known as an orphan branch.  Some git front-ends provide a nice way of doing this but many (even good ones) do not.  No matter, you can always create one from the command line, like so:

...

Now commit and things will be working as expected

Perform bash/shell operations on every commit (and rewrite history)

A few times I've needed to perform certain operations on every commit of a branch in history (like say delete a file that shouldn't have been added to the repo)In a recent case, I was actually separating out multiple code bases from one big repository into several smaller repositories.  Luckily, the repository contained separate folders, where each folder contained separate and independent projects.  So basically I just had to move these folders into separate repositories... while keeping all history for the specific folder only.

This turned out to be fairly straightforward (see, not all things with git are difficult (smile)).

Basically, I created a repo for each project and pushed master (which contained all folders and all changes over the original repo history) to each repo (i.e. basically just created copies of the original repo).  I then checked out each of the just created repos and ran the following from bash (or git bash if you've installed it on windows):

Code Block
themeEmacs
git filter-branch --tree-filter 'ls | grep -v project1-folder | xargs rm -rf; rm -f .gitignore' HEAD

where project1-folder  is the folder that I wanted to keep for this specific repo.  ls | grep -v project1-folder | xargs rm -rf lists all folders EXCEPT project1-folder and then pipes to xargs which runs rm -rf on each (which deletes those other folders). You'll note that I also deleted .gitignore (which contained a whole bunch of ignores for each project - I'll recreate this for each new repo just with the specific ignores relevant to the new repo).

Now git filter-branch can be pretty destructive as it rewrites history, so it creates a backup before the operation.  Once you're happy with the your filtering you can remove this backup with:

Code Block
themeEmacs
rm -rf .git/refs/original/

We have a problem now... we've removed all of the other folders from repo history (which is what we wanted) but it's resulted in lots of empty commits (e.g. when anyone changed files within one of the now deleted folders, these commits are now empty but still existent).

Not to worry, git contains a command for just this case.  The following will go through each commit, and if its empty, will remove it:

Code Block
themeEmacs
git filter-branch --prune-empty

After it is completed, you should now have only those commits that changed files/folders within the actual folder you want to keep (e.g. project-folder1).

You'll also probably want to remove the backup refs (which git creates before pruning empty commits)

Code Block
themeEmacs
rm -rf .git/refs/original/

git can't checkout on windows due to filename too long...

...

Code Block
themeEmacs
git prune

(use 'git prune -n' to see what commits will be pruned without actually pruning).

...