http://massivetechinterview.blogspot.com/2018/02/git-misc-part-5.html
https://git-scm.com/docs/git-reflog
Reference logs, or "reflogs", record when the tips of branches and other references were updated in the local repository. Reflogs are useful in various Git commands, to specify the old value of a reference. For example,
https://stackoverflow.com/questions/2510276/undoing-git-reset
Squashing Git Commits
git init一般是在本地创建一个受Git管理的项目,然后推送到Git服务器,相当于是创建仓库。
https://blog.qikqiak.com/post/a-better-git-log/
Use git-fetch and git-diff to see what evils await you:
git fetch
git diff origin/master
As usual, difftool can be used to launch a preferred diff utility (*cough*meld*cough*).
git diff origin/master
git diff --stat origin/master
...or --dirstat to see what directories have changed:
git diff --dirstat origin/master
https://coderwall.com/p/8dyicg/dry-run-in-git
http://adit.io/posts/2013-08-16-five-useful-git-tips.html
if you lose data but you checked it in somewhere, you can probably recover it. If you didn't check it in, you probably can't. So check in often!
https://git-scm.com/download/gui/mac
sourceTree
https://makandracards.com/makandra/13725-git-how-to-stash-with-a-custom-message
https://stackoverflow.com/questions/11269256/how-to-name-and-retrieve-a-stash-by-name-in-git
https://stackoverflow.com/questions/27451151/is-there-a-git-touch-so-i-can-push-the-same-file-with-a-new-timestamp
https://stackoverflow.com/questions/10018533/is-it-possible-to-git-status-only-modified-files
https://stackoverflow.com/questions/4950725/how-do-i-get-git-to-show-me-which-branches-are-tracking-what
https://howtogit.net/recipes/getting-out-of-detached-head-state.html
You’re not on a branch right now. You’re browsing a snapshot of your Git files from a specific commit in your history. To get out of detached HEAD state and go back to master, do
https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head
http://thesimplesynthesis.com/post/git-error-warning-refname-originbranch-name-is-ambiguous
https://stackoverflow.com/questions/5736987/how-to-switch-to-a-different-remote-branch-in-git
https://gist.github.com/jagregory/710671
So you've cloned somebody's repo from github, but now you want to fork it and contribute back. Never fear!
Technically, when you fork "origin" should be your fork and "upstream" should be the project you forked; however, if you're willing to break this convention then it's easy.
* Off the top of my head *
1. Fork their repo on Github
2. In your local, add a new remote to your fork; then fetch it, and push your changes up to it
git remote add my-fork git@github...my-fork.git
git fetch my-fork
git push my-fork
Otherwise, if you want to follow convention:
1. Fork their repo on Github
2. In your local, rename your origin remote to upstream
git remote rename origin upstream
3. Add a new origin
git remote add origin git@github...my-fork
4. Fetch & push
git fetch origin
git push origin
http://data.agaric.com/undo-git-add-remove-files-staged-git-commit
How to git grep only a set of file extensions
http://stackoverflow.com/questions/6258440/find-a-git-branch-containing-changes-to-a-given-file
How can I get a list of git branches, ordered by most recent commit? Ask Question
http://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit
Use
Also available since Git 2.7.0 for
http://stackoverflow.com/questions/7151311/using-git-how-could-i-search-for-a-string-across-all-branches
http://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit
https://coderwall.com/p/esfncg/git-view-a-file-in-a-different-branch
To view a file in a different git branch (without checking it out) you can run the following:
git show <branch>:<file>
http://stackoverflow.com/questions/7856416/view-a-file-in-a-different-git-branch-without-changing-branches
http://stackoverflow.com/questions/11956710/git-recover-deleted-file-where-no-commit-was-made-after-the-delete
- if not commited, (unstaged), then just git checkout .
Remember to use the period because it tells git to grab all of the files.
https://makandracards.com/makandra/621-git-delete-a-branch-local-or-remote
To delete a local branch
git branch -d the_local_branch
perhaps someone else has already deleted the branch. Try to synchronize your branch list with
- git fetch -p
Use git-fetch and git-diff to see what evils await you:
git fetch
git diff origin/master
git diff --stat origin/master
...or --dirstat to see what directories have changed:
git diff --dirstat origin/master
https://gist.github.com/karlp/408366
https://coderwall.com/p/8dyicg/dry-run-in-git
http://stackoverflow.com/questions/9045435/search-git-commits-using-regex
https://www.atlassian.com/git/tutorials/git-log
displaying commits.
The
Find out who made the change
http://stackoverflow.com/questions/4468361/search-all-of-git-history-for-a-string
git show file in specific commit
http://stackoverflow.com/questions/278192/view-the-change-history-of-a-file-using-git-versioning
http://stackoverflow.com/questions/5288172/git-replace-local-version-with-remote-version
http://stackoverflow.com/questions/1351567/putting-uncommitted-changes-at-master-to-a-new-branch-by-git
Putting uncommitted changes at Master to a new branch by Git
http://stackoverflow.com/questions/1910082/git-stash-apply-version
https://git-scm.com/docs/git-reflog
Reference logs, or "reflogs", record when the tips of branches and other references were updated in the local repository. Reflogs are useful in various Git commands, to specify the old value of a reference. For example,
HEAD@{2}
means "where HEAD used to be two moves ago", master@{one.week.ago}
means "where master used to point to one week ago in this local repository"https://stackoverflow.com/questions/2510276/undoing-git-reset
git reset 'HEAD@{1}'
Long answer:
Git keeps a log of all ref updates (e.g., checkout, reset, commit, merge). You can view it by typing:
git reflog
Somewhere in this list is the commit that you lost. Let's say you just typed
git reset HEAD~
and want to undo it. My reflog looks like this:$ git reflog
3f6db14 HEAD@{0}: HEAD~: updating HEAD
d27924e HEAD@{1}: checkout: moving from d27924e0fe16776f0d0f1ee2933a0334a4787b4c
[...]
The first line says that
https://gist.github.com/patik/b8a9dc5cd356f9f6f980HEAD
0 positions ago (in other words, the current position) is 3f6db14; it was obtained by resetting to HEAD~
. The second line says that HEAD
1 position ago (in other words, the state before the reset) is d27924e. It was obtained by checking out a particular commit (though that's not important right now). So, to undo the reset, run git reset HEAD@{1}
(or git reset d27924e
).Squashing Git Commits
To squash the last 3 commits into one:
git reset --soft HEAD~3
git commit -m "New message for the combined commit"
If the commits have been pushed to the remote:
git push origin +name-of-branch
The plus sign forces the remote branch to accept your rewritten history, otherwise you will end up with divergent branches
https://www.jianshu.com/p/134d257ae4dfgit init一般是在本地创建一个受Git管理的项目,然后推送到Git服务器,相当于是创建仓库。
git checkout -b newBranch (创建并切换)
开发完毕后,我们要切换到master上,想把newBranch合并进来:
注意checkout切换分支的最佳方式是保持工作区域的干净,什么是干净呢?就是把变化的全部提交到newBranch本地版本库,否则git会提示阻止checkout。
git checkout master
git merge newBranch
开发完毕后,我们要切换到master上,想把newBranch合并进来:
注意checkout切换分支的最佳方式是保持工作区域的干净,什么是干净呢?就是把变化的全部提交到newBranch本地版本库,否则git会提示阻止checkout。
git checkout master
git merge newBranch
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
http://entrenchant.blogspot.com/2013/06/git-trick-preview-before-pull.htmlUse git-fetch and git-diff to see what evils await you:
git fetch
git diff origin/master
As usual, difftool can be used to launch a preferred diff utility (*cough*meld*cough*).
git diff origin/master
To see just what files have changed, use the --stat option:
git diff --stat origin/master
...or --dirstat to see what directories have changed:
git diff --dirstat origin/master
With any luck, everything is more or less in sync and you can proceed with your usual git pull.
For those looking for something to add to their .bashrc:
alias git-dry-run='git fetch && git diff --stat origin/master'
For those looking for something to add to their .bashrc:
alias git-dry-run='git fetch && git diff --stat origin/master'
Sometimes when running git commands, you might do stuff you didn’t intend. For instance when running git clean...
git clean -f
Whoops, you have just removed all untracked files from your working tree and even untracked folders (for instance a settings folder of your IDE).
Now this is where ‘dry run’ comes to the rescue. This option will check what the git command is about to do, before actually doing so. You’ll mostly be using the -n option like this:
git clean -n
Not every git command supports the -n option. It sometimes even means something else. For instance in the case of
git commit -n
, which is the –no-verify option, which bypasses the pre-commit and commit-msg hooks. In that case you should use
git merge --dry-run.
git config --global help.autocorrect 1
Now when you make a simple typo, git will correct it automatically!
So you can grep through your code base. But what if the code you're grepping for lives in history? Git allows you to grep through your entire project history quickly and easily using git pickaxe:
git log -S[search term]
git log -Saws_secret_key # did this repo ever have an aws_secret_key?
That will show you all the commits including
aws_secret_key
. You can see the diff of each commit too by passing the -p
flag:git log -Saws_secret_key -p
if you lose data but you checked it in somewhere, you can probably recover it. If you didn't check it in, you probably can't. So check in often!
But they're still there! And you can get to any commit if you know its SHA1 hash! Well lucky for you, there are a couple of ways to figure out the SHA1. One way if to use the
reflog
:reflog
Any action you take that updates a branch head will get logged in your reflog. Check it out by running
git log -g
:commit ee68d62d4cbac3ffefc38398a63d70e4dd518e7d
Reflog: HEAD@{0} (Aditya Bhargava <bluemangroupie@gmail.com>)
Reflog message: commit: Finish writing the kernel
Author: Aditya Bhargava <bluemangroupie@gmail.com>
Date: Tue Aug 13 15:10:55 1991 -0700
Finish writing the kernel
commit 2f9eaea2ce5e6306cb37897417cf63a8d8c63ec4
Reflog: HEAD@{1} (Aditya Bhargava <bluemangroupie@gmail.com>)
Reflog message: checkout: moving from master to adit/experimental
Author: Linus Torvalds <linus@git.com>
Date: Tue Aug 13 14:27:36 1991 -0700
CSS Tweaks
Do you see your lost commits in here? If you do, grab the SHA1 of the newest commit, and do:
git branch lost_data [SHA1]
Now the
lost_data
branch should have all of your lost commits! Merge it into your branch:git merge lost_data
git fsck --full
This shows you all the objects that aren't pointed to by another object. One of your commits should be in this list, and you can get the SHA1 hash!
sourceTree
https://makandracards.com/makandra/13725-git-how-to-stash-with-a-custom-message
https://stackoverflow.com/questions/11269256/how-to-name-and-retrieve-a-stash-by-name-in-git
This is how you do it:
git stash save "my_stash"
where "my_stash" is the stash name...
Some more useful things to know: All the stashes are stored in a stack. Type in :
git stash list
This will list down all your stashes.
To apply a stash and remove it from the stash stack, You can give,
git stash pop stash@{n}
To apply a stash and keep it in the stash stack, type:
git stash apply stash@{n}
Where n in the index of the stashed change.
Eg.
$ git commit --allow-empty -m "Trigger notification"
would cause an empty commit which you can then push and do another deploy.git status | grep modified:
It looks like git status -uno
will show you only files that git is tracking, without showing anything else in the directory. Not exactly what you asked for, but perhaps accomplishes the same thing (getting a readable-length list of files that git tracks).
you could use git ls-files -m
to show all modified files.
https://stackoverflow.com/questions/4950725/how-do-i-get-git-to-show-me-which-branches-are-tracking-what
Very much a porcelain command, not good if you want this for scripting:
git branch -vv # doubly verbose!
You’re not on a branch right now. You’re browsing a snapshot of your Git files from a specific commit in your history. To get out of detached HEAD state and go back to master, do
git checkout master
.- You either executed
git checkout [hash of a commit]
or you tried to switch to an upstream branch (e.g. origin/master) instead of a local branch (e.g. master).
When you run a command like
git checkout [commit hash]
your Git files are rolled back to the state they were in when that commit was made. HEAD will now point to the commit you specified. It’s like switching to another branch, except you’re switching to a specific commit in your Git history.- Running
git checkout [commit hash]
won’t affect your branches in any way. You’re just viewing your history at a certain point in time. When you return to your branch withgit checkout [branch name]
it will still be there in its original state. - Any commits you make in detached HEAD mode will get lost. Git won’t prevent you from making commits in detached HEAD mode, but your commits won’t be added to a branch. Therefore you pretty much lose track of them next time you run a checkoutcommand. If you accidentally lose commits this way, you will have to resort to advanced Git sorcery for a chance to recover them.
- Files that were never added to Git are unaffected by this command. Git doesn’t keep their history, so
git checkout
will not touch them.
What’s the main purpose of detached HEAD state?
The most useful thing you can do with it is explore an older state of a repository. Afterwards, you’ll probably want to return to the branch you came from. You can do this with
git checkout -
. Interesting tidbit about the dash: it’s a shortcut for “the branch or commit you were on before your last checkout command.What else can I do in detached HEAD state?
You can start a new branch from the current commit.
https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commitgit checkout -b [name of your new branch]
will create a new branch from your current HEAD position. You will exit detached HEAD mode when you create a new branch
With the "git checkout" command, you determine which revision of your project you want to work on. Git then places all of that revision's files in your working copy folder.
However, you can also provide the SHA1 hash of a specific commit instead:
$ git checkout 56a4e5c08
Note: checking out '56a4e5c08'.
You are in 'detached HEAD' state...
This exact state - when a specific commit is checked out instead of a branch - is what's called a "detached HEAD".
The problem with a detached HEAD
The HEAD pointer in Git determines your current working revision (and thereby the files that are placed in your project's working directory). Normally, when checking out a proper branch name, Git automatically moves the HEAD pointer along when you create a new commit. You are automatically on the newest commit of the chosen branch.
When you instead choose to check out a commit hash, Git won't do this for you. The consequence is that when you make changes and commit them, these changes do NOT belong to any branch.
This means they can easily get lost once you check out a different revision or branch: not being recorded in the context of a branch, you lack the possibility to access that state easily (unless you have a brilliant memory and can remember the commit hash of that new commit...).
This means they can easily get lost once you check out a different revision or branch: not being recorded in the context of a branch, you lack the possibility to access that state easily (unless you have a brilliant memory and can remember the commit hash of that new commit...).
When a detached HEAD shows up
There are a handful of situations where detached HEAD states are common:
- Submodules are indeed checked out at specific commits instead of branches.
- Rebase works by creating a temporary detached HEAD state while it runs.
This is a perfectly valid and common use case. However, you don't have to maneuver yourself into a detached HEAD state to deal with it. Instead, remember how simple and cheap the whole concept of branching is in Git: you can simply create a (temporary) branch and delete it once you're done.
Reset local repository branch to be just like remote repository HEAD$ git checkout -b test-branch 56a4e5c08 ...do your thing... $ git checkout master $ git branch -d test-branch
https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head
git fetch origin
git reset --hard origin/master
If you want to save your current branch's state before doing this (just in case), you can do:
git commit -a -m "Saving my work, just in case"
git branch my-saved-work
Now your work is saved on the branch "my-saved-work" in case you decide you want it back (or want to look at it later or diff it against your updated branch).
https://stackoverflow.com/questions/572549/difference-between-git-add-a-and-git-addgit add -A
stages Allgit add .
stages new and modified, without deletedgit add -u
stages modified and deleted, without new
git add -A
is equivalent to git add .; git add -u
.
The important point about
git add .
is that it looks at the working tree and adds all those paths to the staged changes if they are either changed or are new and not ignored, it does not stage any 'rm' actions.git add -u
looks at all the already tracked files and stages the changes to those files if they are different or if they have been removed. It does not add any new files, it only stages changes to already tracked files.git add -A
is a handy shortcut for doing both of those.
When this happened, it created the file .git/refs/heads/origin/branch-name. So, I just deleted the file:
https://stackoverflow.com/questions/21311692/git-merge-ambiguous-while-merging-two-branches
Branches in
heads/
are branches local to your repository, which you've created in this clone with git branch
or git checkout -b
. Branches in remotes/
are remote tracking branches, which are read-only copies of branches from other clones that are updated with you run a git fetch
or a git pull
.
When you have branches with the same name in both, you can disambiguate by including the
heads/
or remotes/
prefix:git checkout test
git merge remotes/origin/DEV_66
Since you created
heads/origin/DEV_66
by mistake, you can delete it like so:git branch -d heads/origin/DEV_66
git branch -rv
will show all branches including remote branches, and commit each branch is pointing to at the moment. You can further inspect each branch by viewing log:
Have a look for all the branches first, just input following command in the terminal:
git branch --all
And then you will see the all the branches on local and remote. Something like this:
*master
remotes/origin/develop
remotes/origin/master
remotes/origin/web
remotes/origin/app
Let's pretend you want to switch to the
remotes/origin/develop
branch. Type following:git checkout remotes/origin/develop
Then type
git branch --all
again to find this:*(detached from remotes/origin/develop)
master
remotes/origin/develop
remotes/origin/master
remotes/origin/web
remotes/origin/app
And then just do:
git checkout -b develop
From now on, you are working on the
remotes/origin/develop
branch exactly.https://gist.github.com/jagregory/710671
So you've cloned somebody's repo from github, but now you want to fork it and contribute back. Never fear!
Technically, when you fork "origin" should be your fork and "upstream" should be the project you forked; however, if you're willing to break this convention then it's easy.
* Off the top of my head *
1. Fork their repo on Github
2. In your local, add a new remote to your fork; then fetch it, and push your changes up to it
git remote add my-fork git@github...my-fork.git
git fetch my-fork
git push my-fork
Otherwise, if you want to follow convention:
1. Fork their repo on Github
2. In your local, rename your origin remote to upstream
git remote rename origin upstream
3. Add a new origin
git remote add origin git@github...my-fork
4. Fetch & push
git fetch origin
git push origin
http://data.agaric.com/undo-git-add-remove-files-staged-git-commit
git reset filename.txt
Will remove a file named filename.txt from the current index, the "about to be committed" area, without changing anything else.
To undo git add . use git reset (no dot).
http://stackoverflow.com/questions/21599474/how-to-git-grep-only-a-set-of-file-extentionsHow to git grep only a set of file extensions
git grep "MyFunc" -- '*.cpp' '*.h'
The quotes are necessary so that git expands the wildcards rather than the shell. If you omit them, it'll only search files in the current directory, rather than including subdirectories.
Find a Git branch containing changes to a given filehttp://stackoverflow.com/questions/6258440/find-a-git-branch-containing-changes-to-a-given-file
This is an inelegant brute-force method but I expect it should work. Make sure you've stashed any uncommitted changes first as it will switch which branch you are currently on.
for branch in $(git for-each-ref --format="%(refname:short)" refs/heads); do
git checkout $branch && git grep SOMETHING
done
Find all branches which contain a change to FILENAME (even if before the (non-recorded) branch point)
FILENAME="<filename>"
git log --all --format=%H $FILENAME | while read f; do git branch --contains $f; done | sort -u
Manually inspect:
gitk --all --date-order -- $FILENAME
Find all changes to FILENAME not merged to master:
git for-each-ref --format="%(refname:short)" refs/heads | grep -v master | while read br; do git cherry master $br | while read x h; do if [ "`git log -n 1 --format=%H $h -- $FILENAME`" = "$h" ]; then echo $br; fi; done; done | sort -u
http://stackoverflow.com/questions/18278774/search-git-remote-all-branches-for-file-contentsgit grep 'search-string' $(git ls-remote . 'refs/remotes/*' | cut -f 2)
That will search all remote branches for
search-string
. Since the symbolic reference HEAD
is mirrored, you may end up searching the same commit twice. Hopefully that's not an issue. If so, you can filter it out with:git grep 'search-string' \
$(git ls-remote . 'refs/remotes/*' | grep -v HEAD | cut -f 2)
If you need to dig through your entire history, you can also try:
git grep 'search-string' $(git rev-list --all)
How can I get a list of git branches, ordered by most recent commit? Ask Question
http://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit
Use
--sort=-committerdate
option of git for-each-ref
;Also available since Git 2.7.0 for
git branch
:it for-each-ref --sort=-committerdate refs/heads/
# or using git branch (since version 2.7.0)
git branch --sort=-committerdate # DESC
git branch --sort=committerdate # ASC
Using git, how could I search for a string across all branches?http://stackoverflow.com/questions/7151311/using-git-how-could-i-search-for-a-string-across-all-branches
git rev-list --all | xargs git grep "string/regexp"
In many cases git rev-list --all
can return a huge number of commits taking forever to scan. If you instead of searching through every commit on every branch in your repository history just want to search all branch tips you can replace it with git show-ref --heads
. So in total:
git show-ref --heads | xargs git grep "string"
lists all branches with latest commits:
git branch -v
To order by most recent commit, use
git branch -v --sort=committerdate
git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'
git branch
commands’ various options. -a
shows all local and remote branches, while -r
shows only remote branches.https://coderwall.com/p/esfncg/git-view-a-file-in-a-different-branch
To view a file in a different git branch (without checking it out) you can run the following:
git show <branch>:<file>
http://stackoverflow.com/questions/7856416/view-a-file-in-a-different-git-branch-without-changing-branches
git show somebranch:path/to/your/file
you can also do multiple files and have them concatenated:
git show branchA~10:fileA branchB^^:fileB
You have to provide the full path to the file.
If you want to get the file in the local directory (revert just one file) you can checkout:
git checkout somebranch^^^ -- path/to/file
http://stackoverflow.com/questions/8391506/searching-for-a-file-in-all-git-branches
How do I search all git branches of a project for a file name? I remember part of the filename (just the ending) so I'd like to be able to search for something like
*_robot.php
across all branches, and see which files match that. I'd preferably like to have it search history, and not just the HEADs of branches.git log --all --name-only --pretty=format: | sort -u | grep _robot.php
- if not commited, (unstaged), then just git checkout .
Remember to use the period because it tells git to grab all of the files.
This command will reset the head and unstage all of the changes:
$ git reset HEAD .
Then run this to restore all of the files:
$ git checkout .
To recover all unstaged deletions at once, automatically, without specifying each single path:
git ls-files -d | xargs git checkout --
To recover all staged deletions at once, automatically, without specifying each single path:
git status | grep 'deleted:' | awk '{print $2}' | xargs git checkout --
To delete a local branch
git branch -d the_local_branch
To remove a remote branch (if you know what you are doing!)
git push origin :the_remote_branchperhaps someone else has already deleted the branch. Try to synchronize your branch list with
- git fetch -p
The git manual says
-p, --prune After fetching, remove any remote-tracking branches which no longer exist on the remote.
git diff branch_1..branch_2
That will produce the diff between the tips of the two branches. If you'd prefer to find the diff from their common ancestor to test, you can use three dots instead of two:
git diff branch_1...branch_2git diff -–name-only commit1 commit2 > /path/to/my/file
git diff branch1:file branch2:file
git diff ..master path/to/file
http://stackoverflow.com/questions/520650/make-an-existing-git-branch-track-a-remote-branch
As of Git 1.8.0:
git diff branch1:file branch2:file
git diff ..master path/to/file
http://stackoverflow.com/questions/520650/make-an-existing-git-branch-track-a-remote-branch
As of Git 1.8.0:
git branch -u upstream/foo
Or, if local branch
foo
is not the current branch:git branch -u upstream/foo foo
Or, if you like to type longer commands, these are equivalent to the above two:
git branch --set-upstream-to=upstream/foo
git branch --set-upstream-to=upstream/foo foo
http://stackoverflow.com/questions/17222440/is-there-in-git-git-pull-dry-run-option
I have always relied on the inherent abilities of git to get me back if a merge fails.
To estimate how the merge might occur, you can start like you did with:
$ git fetch origin branch # pull changes but don't merge
$ git diff HEAD..origin/branch # diff your current head to the fetched commit
... personal judgement of potential merge conflicts ...
$ git merge origin/branch # merge with the fetched commit
If things did not go as planned, look at your
reflog
and reset back to your desired state$ git reflog
...
abc987 HEAD@{0}: merge activity
b58aae8 HEAD@{1}: fetch origin/branch
8f3a362 HEAD@{2}: activity before the fetch
...
$ git reset --hard HEAD{2}
http://entrenchant.blogspot.com/2013/06/git-trick-preview-before-pull.htmlUse git-fetch and git-diff to see what evils await you:
git fetch
git diff origin/master
To see just what files have changed, use the --stat option:
git diff --stat origin/master
...or --dirstat to see what directories have changed:
git diff --dirstat origin/master
https://gist.github.com/karlp/408366
https://coderwall.com/p/8dyicg/dry-run-in-git
git clean -f
Whoops, you have just removed all untracked files from your working tree and even untracked folders (for instance a settings folder of your IDE).
Now this is where ‘dry run’ comes to the rescue. This option will check what the git command is about to do, before actually doing so. You’ll mostly be using the -n option like this:
git clean -n
Not every git command supports the -n option. It sometimes even means something else. For instance in the case of
git commit -n
, which is the –no-verify option, which bypasses the pre-commit and commit-msg hooks. In that case you should use
git merge --dry-run.
http://stackoverflow.com/questions/9045435/search-git-commits-using-regex
Newer versions of git support
git log -G<regex>
:git log -G'helper.*function' --full-history --all
it will search for the regex in the diff of each commit, and only display commits which introduced a change that matches the regex.
https://www.atlassian.com/git/tutorials/git-log
The most basic filtering option for
git log
is to limit the number of commits that are displayed. When you’re only interested in the last few commits, this saves you the trouble of viewing all the commits in a pager.git log -3
git log --after="2014-7-1"
get log --after="yesterday"
git log --after="2014-7-1" --before="2014-7-4"
To filter commits by their commit message, use the
--grep
flag. This works just like the --author
flag discussed above, but it matches against the commit message instead of the author.git log --grep="JRA-224:"
git log -- foo.py bar.py
The
--
parameter is used to tell git log
that subsequent arguments are file paths and not branch names. If there’s no chance of mixing it up with a branch, you can omit the --
.git log -S"Hello, World!"
If you want to search using a regular expression instead of a string, you can use the
-G"<regex>"
flag instead.By Range
You can pass a range of commits to
git log
to show only the commits contained in that range. The range is specified in the following format, where <since>
and <until>
are commit references:git log <since>..<until>
This command is particularly useful when you use branch references as the parameters. It’s a simple way to show the differences between 2 branches. Consider the following command:
git log master..feature
The
master..feature
range contains all of the commits that are in the feature
branch, but aren’t in the master
branch
The
git shortlog
command is a special version of git log
intended for creating release announcements. It groups each commit by author and displays the first line of each commit message. This is an easy way to see who’s been working on what.
The
--graph
option draws an ASCII graph representing the branch structure of the commit history. This is commonly used in conjunction with the --oneline
and --decorate
commands to make it easier to see which commit belongs to which branch:git log --graph --oneline --decorate
displaying commits.
The
--oneline
flag condenses each commit to a single line
The
If you want to see the actual changes introduced by each commit, you can pass the --stat
option displays the number of insertions and deletions to each file altered by each commit (note that modifying a line is represented as 1 insertion and 1 deletion). This is useful when you want a brief summary of the changes introduced by each commit. For example, the following commit added 67 lines to the hello.py
file and removed 38 lines:-p
option to git log
.
You can prevent
git log
from displaying these merge commits by passing the --no-merges
flag:git log --no-merges
On the other hand, if you’re only interested in the merge commits, you can use the
--merges
flag:git log --merges
Find out who made the change
http://stackoverflow.com/questions/4468361/search-all-of-git-history-for-a-string
Git can search diffs with the -S option (it's called pickaxe in the docs)
git log -Spassword
This will find any commit that added or removed the string
password
. Here a few options:-p
: will show the diffs. If you provide a file (-p file
), it will generate a patch for you.-G
: looks for differences whose added or removed line matches the given regexp, as opposed to-S
, which "looks for differences that introduce or remove an instance of string".--all
: searches over all branches and tags; alternatively, use--branches[=<pattern>]
or--tags[=<pattern>]
git show file in specific commit
git show <commitHash>:/path/to/file
git show HEAD~4:index.html
For this I'd use:
gitk [filename]
or to follow filename past renames
gitk --follow [filename]
git log -p filename
to let git generate the patches for each log entry.
https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-Historygit help log
One of the more helpful options is
-p
, which shows the difference introduced in each commit. You can also use -2
, which limits the output to only the last two entries:$ git log -p -2
Limiting Log Output
However, the time-limiting options such as
--since
and --until
are very useful. For example, this command gets the list of commits made in the last two weeks:$ git log --since=2.weeks
This command works with lots of formats – you can specify a specific date like
"2008-01-15"
, or a relative date such as "2 years 1 day 3 minutes ago"
.
You can also filter the list to commits that match some search criteria. The
--author
option allows you to filter on a specific author, and the --grep
option lets you search for keywords in the commit messages. (Note that if you want to specify both author and grep options, you have to add --all-match
or the command will match commits with either.)
Another really helpful filter is the
-S
option which takes a string and only shows the commits that introduced a change to the code that added or removed that string. For instance, if you wanted to find the last commit that added or removed a reference to a specific function, you could call:$ git log -Sfunction_name
The last really useful option to pass to
git log
as a filter is a path. If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. This is always the last option and is generally preceded by double dashes (--
) to separate the paths from the options.
I understand the question as this: you want to completely replace the contents of one file (or a selection) from upstream. You don't want to affect the index directly (so you would go through add + commit as usual).
Simply do
git checkout remote/branch -- a/file b/another/file
If you want to do this for extensive subtrees and instead wish to affect the index directly use
git read-tree remote/branch:subdir/
You can then (optionally) update your working copy by doing
git checkout-index -u --force
http://stackoverflow.com/questions/1351567/putting-uncommitted-changes-at-master-to-a-new-branch-by-git
Putting uncommitted changes at Master to a new branch by Git
You can just checkout to the test branch and then commit. You don't lose your uncommited changes when moving to another branch.
Supposing you are at the master branch:
git checkout test
git add .
git add deletedFile1
git add deletedFile2
...
git commit -m "My Custom Message"
It is possible to do (in the deployed repository)
git fetch
git checkout origin/master -- path/to/file
The fetch will download all the recent changes, but it will not put it in your current checked out code (working area).
The checkout will update the working tree with the particular file from the downloaded changes (
origin/master
).http://stackoverflow.com/questions/1910082/git-stash-apply-version
git add -A
is equivalent to git add .; git add -u
.
The important point about
git add .
is that it looks at the working tree and adds all those paths to the staged changes if they are either changed or are new and not ignored, it does not stage any 'rm' actions.git add -u
looks at all the already tracked files and stages the changes to those files if they are different or if they have been removed. It does not add any new files, it only stages changes to already tracked files.git add -A
is a handy shortcut for doing both of those.git add -A
stages Allgit add .
stages new and modified, without deletedgit add -u
stages modified and deleted, without new
git stash pop
throws away the (topmost, by default) stash after applying it, whereas git stash apply
leaves it in the stash list for possible later reuse (or you can then git stash drop
it).
Another way to look at it:
git stash pop
is git stash apply && git stash drop
.
If you haven't been committing anything yet, you're already in the right position.
- Create a new branch:
git checkout -b edge
- Your files haven't changed. Just
git add
what needs to and commit as usual. - When you're done committing on
edge
, switch back tomaster
withgit checkout
andgit merge edge
.
http://stackoverflow.com/questions/6925099/git-stash-changes-apply-to-new-branch
git stash
is equivalent to git stash save
Is the standard procedure not working?
- make changes
git stash save
git branch xxx HEAD
git checkout xxx
git stash pop
Shorter:
- make changes
git stash save
git checkout -b xxx
git stash pop
To move these changes to a new branch, run this command where “mybranch” is the name of the branch you want to create.
1: git checkout -b mybranch
and then run git status again. You’ll see that the changes you made are still in place and you can now commit them to the new branch.
http://stackoverflow.com/questions/5741407/how-to-undo-a-git-merge-with-conflicts
Then, while on
mybranch1
, I have done git merge --no-commit mybranch2
It shows there were conflicts while merging.
Now I want do discard everything (the
merge
command) so that mybranch1
is back to what it was before. git merge --abort
This attempts to reset your working copy to whatever state it was in before the merge. That means that it should restore any uncommitted changes from before the merge, although it cannot always do so reliably. Generally you shouldn't merge with uncommitted changes anyway.
Prior to version 1.7.4:
git reset --merge
This is older syntax but does the same as the above.
Prior to version 1.6.2:
git reset --hard
which removes all uncommitted changes, including the uncommitted merge. Sometimes this behaviour is useful even in newer versions of Git that support the above commands.
git merge --abort
is equivalent to git reset --merge
when MERGE_HEAD
is present.MERGE_HEAD
is present when a merge is in progress.
Also, regarding uncommitted changes when starting a merge:
If you have changes you don't want to commit before starting a merge, just
git stash
them before the merge and git stash pop
after finishing the merge or aborting it.HEAD This is an alias for the tip of the current branch, which is the most recent commit you have made to that branch.
The index, also known as the staging area, is the set of files that will become the next commit. It is also the commit that will become HEAD’s parent.
Working Copy This is the term for the current set of files you’re working on in your file system.
If you just look at the reset command by itself, all it does is reset HEAD (the tip of the current branch) to another commit.
git reset HEAD
… nothing happens. This is because we tell git to reset this branch to HEAD, which is where it already is. But if we do:
> git reset HEAD~1
(HEAD~1 is shorthand case for “the commit right before HEAD”, or put differently “HEAD’s parent”)
git reset HEAD~2The
--soft
parameter tells Git to reset HEAD to another commit, but that’s it. If you specify --soft
Git will stop there and nothing else will change. What this means is that the index and working copy don’t get touched, so all of the files that changed between the original HEAD and the commit you reset to appear to be staged.The
--mixed
parameter (which is the default if you don’t specify anything) will reset HEAD to another commit, and will reset the index to match it, but will stop there. The working copy will not be touched. So, all of the changes between the original HEAD and the commit you reset to are still in the working copy and appear as modified, but not staged.The
--hard
parameter will blow out everything – it resets HEAD back to another commit, resets the index to match it, and resets the working copy to match it as well. This is the more dangerous of the commands and is where you can cause damage. Data might get lost here*!You can recover it using
git reflog
https://gist.github.com/tnguyen14/0827ae6eefdff39e452b
- A - B - C (master)
HEAD
points to C
and the index matches C
.--soft
When we run
git reset --soft B
, master
(and thus HEAD
) now points to B
, but the index still has the changes from C
; git status
will show them as staged. So if we run git commit
at this point, we'll get a new commit with the same changes as C
.--mixed
Okay, so starting from here again:
- A - B - C (master)
Now let's do
git reset --mixed B
. Once again, master
and HEAD
point to B, but this time the index is also modified to match B
. If we run git commit
at this point, nothing will happen since the index matches HEAD
. We still have the changes in the working directory, but since they're not in the index, git status
shows them as unstaged. To commit them, you would git add
and then commit as usual.
And finally,
--hard
is the same as --mixed
(it changes your HEAD
and index), except that --hard
also modifies your working directory. If we're at C
and run git reset --hard B
, then the changes added in C
, as well as any uncommitted changes you have, will be removed, and the files in your working copy will match commit B
. Since you can permanently lose changes this way, you should always run git status
before doing a hard reset to make sure your working directory is clean or that you're okay with losing your uncommitted changes.
You can see the commits and changes between tags if you change the URL to the following format:
https://github.com/{username}/{repo}/compare/{older-tag}...{newer-tag}
http://stackoverflow.com/questions/2364147/how-to-get-just-one-file-from-another-branch
Suppose
you're on master
branch, to get app.js from new-feature
branch do:git checkout new-feature path/to/app.js
// note that there is no leading slash in the path!
This will bring you the contents of the desired file. You can, as always, use part of sha1 instead ofnew-feature branch name to get the file as it was in that particular commit.
Not from the GitHub web interface itself, as mentioned in "How to search for a commit message in github?": only
master
is indexed.
Your best bet is to clone the repo, and there, search in all branches. (with
http://stackoverflow.com/questions/10940981/git-how-to-create-a-new-branch-from-a-taggit log -S
for instance)git checkout -b newbranch v1.0
Another variant of the merge is to use
-no-ff
option (it stands for no fast-forward). In this case, the history looks slightly different (right side), there is an additional commit (dotted circle) emphasizing the merge. This commit even has the right message informing us about the merged branch.
Unfortunately, at least as of now, GitHub’s web interface will perform the merge as if you would specify
-no-ff
. In other words, even if there is a possibility of fast-forwarding, GitHub will not do that. One possible explanation is so that the pull request could be identified.
In short, non fast-forward merge keeps the notion of explicit branches . It may complicate the commit history with its non-linear outcome at the price of preserving the source of the branches (pull requests, when using GitHub). On the other hand, fast-forward merge keeps the changesets in a linear history, making it easier to use other tools (log, blame, bisect). The source of each branch will not be obvious, although this is not a big deal if the project mandates the strict cross-referencebetween the commit message and its issue tracker.
git log --first-parent
https://developer.atlassian.com/blog/2015/01/a-better-pull-request/
https://makandracards.com/makandra/13043-force-github-pull-requests-to-update-the-diff-against-its-target-branch
https://makandracards.com/makandra/13043-force-github-pull-requests-to-update-the-diff-against-its-target-branch
tried not work
http://blog.differential.com/best-way-to-merge-a-github-pull-request/
Floating release branch
A branch used just as a "pointer" to a specific commit to have jenkins (or other automation) check it out, build and publish the artifacts produced.
No pull request should ever be opened against such branch.
The branch should be created, used, then deleted. Next time, it is created at a different point of the git history.