Skip to content

Instantly share code, notes, and snippets.

@DevoKun
Last active October 3, 2021 01:45
Show Gist options
  • Save DevoKun/da52292d11a395f90ab5d925d9ac1130 to your computer and use it in GitHub Desktop.
Save DevoKun/da52292d11a395f90ab5d925d9ac1130 to your computer and use it in GitHub Desktop.
Git Tricks I use stored in a handy place

undo git rm $FILENAME or git add -A

##
## Restore the file status in the index
##
git reset -- <file>

##
## check out a copy from the index
##
git checkout -- <file>

Merge files from a different branch

git checkout \
  ${BRANCH_NAME} \
  ${FILENAME1} \
  ${FILENAME2}

Find commits where a specific file changed

git log --follow -- filename

Find binary blobs in git commit history

git log --all --numstat \
    | grep '^-' \
    | cut -f3 \
    | sed -r 's|(.*)\{(.*) => (.*)\}(.*)|\1\2\4\n\1\3\4|g' \
    | sort -u

Remove binary blobs from commit history using BFG

wget -O ~/bin/bfg.jar http://repo1.maven.org/maven2/com/madgag/bfg/1.12.0/bfg-1.12.0.jar
alias 'bfg=java -jar ~/bin/bfg.jar'

bfg --no-blob-protection --strip-blobs-bigger-than 50M

bfg --no-blob-protection --delete-files consul
bfg --no-blob-protection --delete-files consul_1.4.0_linux_amd64.zip

git reflog expire --expire=now --all && git gc --prune=now --aggressive

git push -f

Undo a Git Add

git reset HEAD $FILENAME

Use meld as a diff/merge tool

cat << EOF > ~/.gitconfig
[diff]
  external = ${HOME}/bin/git-diff.sh
EOF

cat << EOF > ~/bin/git-diff.sh
#!/bin/bash

if [ "$5" == "-merge" ]; then
  /usr/local/bin/meld "$6" "$1" "$2" "$4"
else
  /usr/local/bin/meld "$2" "$5"
fi
EOF

chmod +x ~/bin/git-diff.sh

brew install meld

Undo a commit and redo

This is most often done when you fat-finger a commit message. Leaves working tree as it was before commit.

git commit ...
git reset --soft HEAD~1

Combe two git repositories

That is, merge Repo B in to Repo A

##
## In Repo B
##
git remote -v
git remote rm origin
git remote add origin url_to_repo_A
git remote -v

##
## Rename the local master branch of B:
##
git checkout master
git branch -m master-holder

##
## Pull all the code of A into local repo B.
## [B] <------- [A]
##
git fetch
git checkout master
git pull origin master

git merge master-holder --allow-unrelated-histories
git push origin master

Merge specific files from a different branch

git checkout Feature/branch fileA.rb fileB.rb FileC.rb

Change Commiter eMail

git filter-branch -f --commit-filter 'if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ];
  then export GIT_COMMITTER_EMAIL="[email protected]"; export [email protected]; fi; git commit-tree "$@"'


git filter-branch -f --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Devon Hubner" ];
  then export GIT_COMMITTER_EMAIL="[email protected]"; export [email protected]; fi; git commit-tree "$@"'

git push -f

Sync a fork of a repository to keep it up-to-date with the upstream repository.

This BIG-gotcha difference between Stash Bitbucket and GitHub

  • BitBucket auto-syncs repo changes from the original to the forked repo.
  • Which means once we merge something, everybody gets it automatically and just pulls the latest.
  • However, GitHub does not do that.
  • So your personal fork can get out of sync
  • The instructions below will allow you to resync from the upstream master.

Configure a remote for a fork

  • Before you can sync your fork with an upstream repository, you must configure a remote that points to the upstream repository in Git.
  • You must configure a remote that points to the upstream repository in Git to sync changes you make in a fork with the original repository.
  • This also allows you to sync changes made in the original repository with the fork.
##
## List the current configured remote repository for your fork.
##
git remote -v

# origin  [email protected]:DevoKun/ProDOS-8.github.io.git (fetch)
# origin  [email protected]:DevoKun/ProDOS-8.github.io.git (push)

##
## Specify a new remote upstream repository that will be synced with the fork.
##
git remote add upstream [email protected]:ProDOS-8/ProDOS-8.github.io.git

##
## Verify the new upstream repository you've specified for your fork.
##
git remote -v

# origin    [email protected]:DevoKun/ProDOS-8.github.io.git (fetch)
# origin    [email protected]:DevoKun/ProDOS-8.github.io.git (push)
# upstream  [email protected]:ProDOS-8/ProDOS-8.github.io.git (fetch)
# upstream  [email protected]:ProDOS-8/ProDOS-8.github.io.git (push)

Fetch from upstream and merge to local master

git fetch upstream

##
## If not on master, switch to master
## master is not the same as upstream/master
## upstream/master is on github
## master is local to your laptop
##
git branch
git checkout master
git branch
git merge upstream/master

Create a script to resync the branch for you

  • Create the file: ~/bin/gitresync
  • The contents will be:
git remote -v

git fetch upstream
git branch
git checkout master
git branch
git merge upstream/master

List files changed in a commit

git diff-tree --no-commit-id --name-only -r $COMMIT_ID

Revert (reset) changes to a file if they haven’t been committed yet:

git checkout -- <file>

commit from a different date

## works with relative time
git commit --date="10 day ago" -m "commit message" 

## works with iso time
git commit --date="Fri 06 Nov 2020 20:19:19 EST"

## works with unix time
git commit --date="1603726641" -m "commit message"

D=$(ls -al --time-style="+%s" commit_me.txt | awk '{print $6}')
git commit --date="${D}" -m "commit message"

Change date of an existing commit

git filter-branch --env-filter \
    'if [ $GIT_COMMIT = 304a76a8129591ab6a6d1556507e81b76a0e8e8b ]
     then
         export GIT_AUTHOR_DATE="Friday, September 30 14:00 2021"
         export GIT_COMMITTER_DATE="Friday, September 30 14:00 2021"
     fi'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment