checkout a file from an earlier commit without staging
I wanted to revert a file from an earlier commit, but without staging it, so I could discard some hunks:
git restore --source <commit> path/to/file
Thanks to this question: https://stackoverflow.com/questions/50158417/git-checkout-file-from-branch-without-changing-index
Initialising a new repo with a different initial branch
After working on some new code, I realised I wanted to push it to an existing remote git repo, but in a branch that didn't exist. The code hadn't been pulled from anywhere - it was newly written in a directory.
Initialise the directory with the branch that you want it to become, commit the code, add the existing remote and push:
git init --initial-branch=my-fun-feature
git add -A && git commit -m "WIP"
git remote add origin example.org:~/example.git
git push --set-upstream origin my-fun-feature
--single-branch
checkout
Tracking remote branches after a If you single-branch cloned a repo, you can't track and checkout other branches as you normally would. First you need to explicitly add them:
git remote set-branches --add origin feature/weevils
git fetch origin
git checkout feature/weevils
If you don't do this, then typically you'd see:
git checkout --track feature/weevils
$ fatal: 'feature/weevils' is not a commit and a branch 'weevils' cannot be created from it
Do a pickaxe style search through all your stashes
git stash list -S "the thing" -p
A treasure trove of git scripts
John Wiegley has a ton of useful git scripts which he's collected from around the net: https://github.com/jwiegley/git-scripts
Fast forwarding a branch without checking it out
https://samuelgruetter.net/blog/2018/08/31/git-ffwd-without-checkout/ has a really nice post about branch fast forwarding and fetching, and some detail on what's going on when you do something like:
git fetch origin master:master
And even more interestingly:
git fetch . feature:master
where you're fetching from your local repo .
and pushing from your feature
branch to your master
branch.
Remove all local tracking branches to a remote & then delete the remote
git remote prune origin && git remote rm origin
commit or stash your changes
warning
Force checkout a branch to avoid the Sometimes when you want to checkout a branch, even though your current branch is clean, you'll get a failed partial checkout, because a file in your current branch will be changed by the new branch (Looking at you .xcodeproj
files). As long as you know your current branch is clean and up-to-date, -f
force the checkout
git checkout -f the_branch
-reset --hard HEAD
?
Getting merge conflicts when pulling even after git fetch origin
git reset --hard origin/master
Hard reset to HEAD a single file
git checkout HEAD -- some/folder/or/file/path
Want to go back to yesterday, a week ago, 2 months ago, to a specific date?
git checkout @{yesterday}
git checkout @{1.week.ago}
git checkout @{2.months.ago}
git checkout @{"2019-04-26"}
Via https://twitter.com/jaygooby/status/996308522680897537 - loads more git date usages here: https://alexpeattie.com/blog/working-with-dates-in-git
Want to save your work to a stash but still keep those changes in your working directory?
git stash save --keep-index
Did you screw something up using git?
You should take a look at http://ohshitgit.com/ :)
View a file in a previous commit or stash or other commit-ish place
To view, but not checkout a file, use a commit-ish object like a commit sha, short sha, head or stash identifier
git show 250022c63fab80030dcbc72e8b4bf5aa683d8633:file.txt
git show 250022c63:file.txt
git show stash@{2}:file.txt
Squash all commits in a branch down to a single commit
Great for when you're ready to push your local branch with loads of tiny commits to a public repo, or you want to issue a pull request without all your legacy commits. I didn't want to rebase and squash interactively, because I knew in this case that I wanted a single clean commit to start a new public repository with.
git reset $(git commit-tree HEAD^{tree} -m "A new start")
Found at https://stackoverflow.com/a/23486788/391826 - it's the One Liner solution.
Push all branches to from remote to another remote
This will push all branches on remote-x to remote-y without you needing to have local copies
git push remote-y refs/remotes/remote-x/*:refs/heads/*
You'll need to do the same for tags:
git push remote-y refs/tags/*:refs/tags/*
Thanks to https://stackoverflow.com/a/21133502/391826
Push all branches to new remote
If you've added a new remote, you might want to push all your branches to it:
git push new-remote --all
View log in different branch
Maybe you want to cherry-pick from a different branch and you need to know the commit hash:
git log different-branch
You can also look at the log for a specific file on that branch:
git log different-branch path/to/file
Side-by-side diff
git difftool -y -x "diff --suppress-common-lines -y -W 225" master 0ce112bd6dcbedd128566ce712d8cb5d98d765ae |less
-x
to execute the diff command, -y
for side-by-side, -W
for width of lines
Which branch is a specific commit on?
git branch --contains 90be408084cc37b3bcc67eaf0b406ca4f1f381fd
Thanks http://stackoverflow.com/a/1419637/391826
Show non-merge commits to a branch
git log --first-parent --no-merges HEAD
Escape from detached head state
You just need to checkout the branch you want, e.g.
git checkout master
List branches by most recently changed
git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'
and if you want the most recently changed remote branches, swap refs/heads
for refs/remotes
. Both these via Stackoverflow.
git for-each-ref --count=30 --sort=-committerdate refs/remotes/ --format='%(refname:short)'
Grep through all stashed code
git stash list -p | grep -i foo
Pickaxe search all branches
git log --all -S"foo" -p
Ignore line-ending differences when diffing
(You can't use this with git difftool or merge though)
git diff --ignore-space-at-eol
Prefer one branch over another when merging
Got a conflict during a merge? Know that you only care about the file in the other branch?
git checkout --theirs file/that/has/conflict
Know that yours is the correct one?
git checkout --ours file/that/has/conflict
Want to merge but know that you want your files to win any conflicts?
git merge -s recursive -X ours
Change a commit message
git commit --amend -m "New commit message"
Add forgotten files to last commit
git add forgotten_file other_forgotten_file ...
git commit --amend
Give a stash a meaningful name
git stash save "Nearly finished the blah feature, but have to fix yak first"
Show stashed files
git stash show stash@{1}
Diff a specific file with one in stash
git diff some_branch:spec/blueprints.rb stash@{1}:spec/blueprints.rb
Diff just files in stash with a branch
# git difftool stash@{1}
# would diff the whole current branch against the stash,
# you probably just want the diffs of the files in the stash
for file in `git stash show --name-only stash@{1}`; do git difftool your_branch:$file stash@{1}:$file; done
Extract a single file from a stash
git checkout stash@{1} -- path/of/file/in/stash.rb
# note, can also pass multiple files to get them all at once
# git checkout stash@{1} -- path/of/file/in/stash.rb path/to/file2.txt path/to/another/file.jpg
Diffing uncommitted versus HEAD
# When you diff you can look at the files committed in HEAD, versus those on disk
#
# on disk:
git diff stash@{0}:spec/blueprints.rb spec/blueprints.rb
# in HEAD:
git diff stash@{0}:spec/blueprints.rb HEAD:spec/blueprints.rb
# staged:
git diff stash@{0} -- spec/blueprints.rb
# this omission of the filename and the separation with -- from the stash works with the other examples too
Diff what's going to be merged
# You're working in feature/my-branch and you want to merge from master
#
# git fetch origin master
# git difftool feature/my-branch...origin/master
#
# Note the three ...
# Without them you're comparing? which is a different thing entirely
# if it's all looking good, then git merge origin master