Search by tag: git
I needed to know the exact list of files that had been modified between my last two tags:
git diff --name-only v2.0.0 v2.0.1
You can replace the tags by commits:
git diff --name-only SHA1 SHA2 git diff --name-only HEAD~10 HEAD~5
I have slightly different i3 configuration files between my desktop and laptop computers. In this case, the laptop keyboard is missing a Play/Pause multimedia key. This is where the two files differ: the laptop has a different key binding for running the music player.
Having recently added new key bindings to the desktop configuration, I wanted to merge those new lines into the laptop configuration file, without overwriting its specific lines. After trials and errors and thanks to precious clues found on the Internet, I found the patch flag of git-checkout. From the branch specific to my laptop configuration, I ran:
$ git checkout -p master .config/i3/config
This displays an output similar to git-diff, based on the local file .config/i3/config and the one in the branch 'master'. For each conflicts, Git asks:
Apply this hunk to index and worktree [y,n,q,a,d,/,j,J,g,e,?]?
I answered 'n'o to preserve the part specific to the laptop, and 'y'es for the new key bindings I wanted to copy.
First note: if you are not alone on the project, consult with your colleagues before doing this. Because we are about to rewrite history and other contributors will be forced to manually rewrite their history too.
Second note: if what you want to remove is sensitive material (e.g. passwords), consider everything compromised. Unless you are 100% sure that absolutely no one has had any access to your repository. And you are not, are you? Even with your super-secure unbreakable security measures... No, you are not.
Okay, you have been warned.
Let's say we want to remove all traces of a file named "hardcoded_passphrase.txt". We need the sha1 of the commit where this file first appeared. If you don't know, just use the first commit. In this example, the sha1 is bb9c2d4:
$ git filter-branch --index-filter 'git update-index --remove path/to/hardcoded_passphrase.txt' bb9c2d4..HEAD $ git push --force --verbose --dry-run $ git push --force
Having still not the automatic reflexes for applying a successful Git branching model, I cleaned up my working repository a little too fast by deleting a hot-fix branch after merging it into the master branch.
$ git branch -d hotfix-2014062501 Deleted branch hotfix-2014062501 (was 742134c).
When I came back to the development branch I was working on before the emergency, I realised that I just forgot to merge the hot-fix into it.
As often with Git, a simple solution exists. We only need the sha1 of that branch last commit, which was conveniently displayed in the output of the deletion command above, and execute this one-liner:
$ git branch hotfix-2014062501 742134c
The branch should now be back as if nothing happened:
$ git branch -v [...] hotfix-2014062501 742134c some helpful comment
I wanted to do some clean-up on a remote repository, which contained a lot of obsolete branches. But one of them returned the following error:
$ git push origin :alpha remote: error: By default, deleting the current branch is denied, because the next remote: error: 'git clone' won't result in any file checked out, causing confusion. remote: error: remote: error: You can set 'receive.denyDeleteCurrent' configuration variable to remote: error: 'warn' or 'ignore' in the remote repository to allow deleting the remote: error: current branch, with or without a warning message. remote: error: remote: error: To squelch this message, you can set it to 'refuse'. remote: error: refusing to delete the current branch: refs/heads/alpha To remote_repository_uri.git ! [remote rejected] alpha (deletion of the current branch prohibited) error: failed to push some refs to 'remote_repository_uri.git'
As this verbose message explains, I was trying to delete the branch named "alpha", which was set as the current branch on the remote repository.
It was an old branch untouched for several months and I don't know how it has been set to be the current branch instead of master. Since the remote is a bare repository, I could not execute the usual
git checkout master command. The solution is to move HEAD, which is a symbolic link pointing to the current branch. To make that link point to the master branch, execute the following command on the remote server:
$ git symbolic-ref HEAD refs/heads/master
We can verify where HEAD is pointing to with the same
git symbolic-ref command:
$ git symbolic-ref HEAD refs/heads/master