https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head
https://git-scm.com/docs/git-clean
-d
-f
--force
-i
--interactive
-n
--dry-run
-x
-X https://stackoverflow.com/questions/4770177/git-patch-does-not-apply
How to undo “git commit --amend” done instead of “git commit”
https://git-scm.com/docs/git-rm
--cached
https://stackoverflow.com/questions/1143796/remove-a-file-from-a-git-repository-without-deleting-it-from-the-local-filesyste
Remove a file from a Git repository without deleting it from the local filesystem
https://stackoverflow.com/questions/17404316/the-following-untracked-working-tree-files-would-be-overwritten-by-merge-but-i/33803997
https://stackoverflow.com/questions/4950725/how-to-see-which-git-branches-are-tracking-which-remote-upstream-branch
which git branches are tracking which remote / upstream branch?
Or you can use the
https://www.clock.co.uk/insight/deleting-a-git-commit
Rule #2: Create a new branch for every new feature
http://blog.jobbole.com/114297/
Q11: 是么时候使用“git rebase”代替“git merge”?
Q10: 如何从 git 中删除文件,而不将其从文件系统中删除?
https://stackoverflow.com/questions/2304087/what-is-head-in-git
HEAD
https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git
<rev>^, e.g. HEAD^, v1.5.1^0
A suffix ^ to a revision parameter means the first parent of that commit object. ^<n> means the <n>th parent (i.e. <rev>^ is equivalent to <rev>^1). As a special rule, <rev>^0 means the commit itself and is used when <rev> is the object name of a tag object that refers to a commit object.
<rev>~<n>, e.g. master~3
A suffix ~<n> to a revision parameter means the commit object that is the <n>th generation ancestor of the named commit object, following only the first parents. I.e. <rev>~3 is equivalent to <rev>^^^ which is equivalent to <rev>^1^1^1. See below for an illustration of the usage of this form.
https://stackoverflow.com/questions/964876/head-and-orig-head-in-git
https://git-scm.com/docs/git-reset
Undo a merge or pull inside a dirty working tree
https://henrikwarne.com/2018/06/25/6-git-aha-moments/
Committed changes can be reset to local changes again
“git reset HEAD~
https://stackoverflow.com/questions/594757/how-do-i-do-a-git-status-so-it-doesnt-display-untracked-files-without-using
git status -uno
which is equivalent to:
git status --untracked-files=no
It's a bit hidden in the manuals, but the manpage for status says "supports the same options as git-commit", so that's where you'd have to look.
https://stackoverflow.com/questions/22565184/git-how-to-revert-after-a-merge-conflict-corruption
All of the above suggests are right, but often to really reset your project, you also need to remove even files that are in your
.gitignore
.
To get the moral equivalent of erasing your project directory and re-cloning from the remote is:
git fetch
git reset --hard
git clean -x -d -f
Warning:
git clean -x -d -f
is irreversible and you may lose files and data (e.g. things you have ignored using .gitignore
).
git-clean - Remove untracked files from the working tree
Cleans the working tree by recursively removing files that are not under version control, starting from the current directory.
Remove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use -f option twice if you really want to remove such a directory.
If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to delete files or directories unless given -f, -n or -i. Git will refuse to delete directories with .git sub directory or file unless a second -f is given.
Show what would be done and clean files interactively. See “Interactive mode” for details.
Don’t actually remove anything, just show what would be done.
-x
Don’t use the standard ignore rules read from .gitignore (per directory) and $GIT_DIR/info/exclude, but do still use the ignore rules given with
-e
options. This allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset) to create a pristine working directory to test a clean build.
Remove only files ignored by Git. This may be useful to rebuild everything from scratch, but keep manually created files.
This command will apply the patch not resolving it leaving bad files as
*.rej
:git apply --reject --whitespace=fix mypath.patch
https://stackoverflow.com/questions/1459150/how-to-undo-git-commit-amend-done-instead-of-git-commitHow to undo “git commit --amend” done instead of “git commit”
What you need to do is to create a new commit with the same details as the current
HEAD
commit, but with the parent as the previous version of HEAD
. git reset --soft
will move the branch pointer so that the next commit happens on top of a different commit from where the current branch head is now.# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}
# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
git commit -C HEAD@{1}
Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.
Remove a file from a Git repository without deleting it from the local filesystem
For single file:
git rm --cached mylogfile.log
For single directory:
git rm --cached -r mydirectory
On my branch I had some files in .gitignore
On a different branch those files are not.
I want to merge the different branch into mine, and I don't care if those files are no longer ignored or not.
Unfortunately I get this:
The following untracked working tree files would be overwritten by merge
How would I modify my pull command to overwrite those files, without me having to find, move or delete those files myself?
The problem is that you are not tracking the files locally but identical files are tracked remotely so in order to "pull" your system would be forced to overwrite the local files which are not version controlled.
Try running
git add *
git stash
git pull
This will track all files, remove all of your local changes to those files, and then get the files from the server.
which git branches are tracking which remote / upstream branch?
git branch -vv # doubly verbose!
Note that with git 1.8.3, that upstream branch is displayed in blue (see "What is this branch tracking (if anything) in git?")
https://stackoverflow.com/questions/4878249/how-to-change-the-remote-a-branch-is-trackingUsing git v1.8.0 or later:
git branch branch_name
--set-upstream-to
your_new_remote/branch_name
Or you can use the -u
switch:
git branch branch_name
-u
your_new_remote/branch_name
If it is the last commit this is very straight forward. Simply run:
git reset HEAD
Using the git log above we want to remove the following commits; 2 & 3 (ae45fab & 77b9b82). As they are consecutive commits we can use rebase.
git rebase --onto <branch name>~<first commit number to remove> <branch name>~<first commit to be kept> <branch name>
e.g to remove commits 2 & 3 above
git rebase --onto repair~3 repair~1 repair
Rule #2: Create a new branch for every new feature
Q11: 是么时候使用“git rebase”代替“git merge”?
这两个命令都是把修改从一个分支集成到另一个分支上,它们只是以非常不同的方式进行。
考虑一下场景,在合并和变基前:
1
2
3
4
|
A <- B <- C [master]
^
\
D <- E [branch]
|
在
git merge master
之后:
1
2
3
4
|
A <- B <- C
^ ^
\ \
D <- E <- F
|
在
git rebase master
之后:
1
|
A <- B <- C <- D <- E
|
使用变基时,意味着使用另一个分支作为集成修改的新基础。
- 是否无论如何都要还原合并?恢复(如在撤销中)变基,是相当困难的,并且/或者在变基中存在冲突时,是不可能完成的。如果你考虑到日后可能需要恢复,请使用合并操作。
Q10: 如何从 git 中删除文件,而不将其从文件系统中删除?
如果你在
git add
过程中误操作,你最终会添加不想提交的文件。但是,git rm
则会把你的文件从你暂存区(索引)和文件系统(工作树)中删除,这可能不是你想要的。
换成
git reset
操作:
1
2
|
git reset filename # or
echo filename >> .gitingore # add it to .gitignore to avoid re-adding it
|
上面意思是,
git reset <paths>
是 git add <paths>
的逆操作。
You can think of the HEAD as the "current branch". When you switch branches with
git checkout
, the HEAD revision changes to point to the tip of the new branch.
You can see what HEAD points to by doing:
cat .git/HEAD
In my case, the output is:
$ cat .git/HEAD
ref: refs/heads/master
The current branch. In more detail: Your working tree is normally derived from the state of the tree referred to by HEAD. HEAD is a reference to one of the heads in your repository, except when using adetached HEAD, in which case it directly references an arbitrary commit.
Both
~
and ^
on their own refer to the parent of the commit (~~
and ^^
both refer to the grandparent commit, etc.) But they differ in meaning when they are used with numbers:~2
means up two levels in the hierarchy, via the first parent if a commit has more than one parent^2
means the second parent where a commit has more than one parent (i.e. because it's a merge)
These can be combined, so
HEAD~2^3
means HEAD
's grandparent commit's third parent commit.HEAD^
means the first parent of the tip of the current branch.
Remember that git commits can have more than one parent.
HEAD^
is short for HEAD^1
, and you can also address HEAD^2
and so on as appropriate.
You can get to parents of any commit, not just
https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-rev-parse.htmlHEAD
. You can also move back through generations: for example, master~2
means the grandparent of the tip of the master branch, favoring the first parent in cases of ambiguity. These specifiers can be chained arbitrarily , e.g., topic~3^2
.https://stackoverflow.com/questions/964876/head-and-orig-head-in-git
HEAD
is (direct or indirect, i.e. symbolic) reference to the current commit. It is a commit that you have checked in the working directory (unless you made some changes, or equivalent), and it is a commit on top of which "git commit" would make a new one. Usually HEAD
is symbolic reference to some other named branch; this branch is currently checked out branch, or current branch. HEAD
can also point directly to a commit; this state is called "detached HEAD", and can be understood as being on unnamed, anonymous branch.
And
@
alone is a shortcut for HEAD
, since Git 1.8.5ORIG_HEAD
is previous state of HEAD
, set by commands that have possibly dangerous behavior, to be easy to revert them. It is less useful now that Git has reflog: HEAD@{1}
is roughly equivalent to ORIG_HEAD
(HEAD@{1}
is always last value of HEAD
, ORIG_HEAD
is last value of HEAD
before dangerous operation)."pull" or "merge" always leaves the original tip of the current branch inORIG_HEAD
.
git reset --hard ORIG_HEAD
Resetting hard to it brings your index file and the working tree back to that state, and resets the tip of the branch to that commit.
Instead of typing four capital letters "HEAD
", you can say "@
" now,
e.g. "git log @
".
Typing '
HEAD
' is tedious, especially when we can use '@
' instead.
The reason for choosing '
@
' is that it follows naturally from the ref@op
syntax (e.g. HEAD@{u}
), except we have no ref, and no operation, and when we don't have those, it makes sens to assume 'HEAD
'.
So now we can use '
git show @~1
', and all that goody goodness.
HEAD means "current" everywhere in git, but it does not necessarily mean "current branch" (i.e. detached HEAD).
git-reset - Reset current HEAD to the specified state
$ git pull (1) Auto-merging nitfol Merge made by recursive. nitfol | 20 +++++---- ... $ git reset --merge ORIG_HEAD (2)
- After inspecting the result of the merge, you may find that the change in the other branch is unsatisfactory. Running "git reset --hard ORIG_HEAD" will let you go back to where you were, but it will discard your local changes, which you do not want. "git reset --merge" keeps your local changes.
Committed changes can be reset to local changes again
“git reset HEAD~
https://stackoverflow.com/questions/594757/how-do-i-do-a-git-status-so-it-doesnt-display-untracked-files-without-using
git status -uno
which is equivalent to:
git status --untracked-files=no
It's a bit hidden in the manuals, but the manpage for status says "supports the same options as git-commit", so that's where you'd have to look.
https://stackoverflow.com/questions/22565184/git-how-to-revert-after-a-merge-conflict-corruption
Your two problems can be solved in the same way:
git checkout HEAD my/filename.js
Where HEAD is literal (git shorthand for current branch name) and my/filename.js should be replaced by the actual filename of your file. This will restore your file to how it was before the update, effectively "undoing" the changes from the other person. Commit this result locally and then push as normal (no --force should be necessary if you when you have updated from the central repo)
In general, the way to resolve a merge conflict is to edit your file until it's the way you want it, and then run git add. The reason git (and svn for that matter) leave the "<<<" and ">>>" results in your file after a failed merge or update is to help you or your tools to resolve the merge. Setting up a tool to help you do this will probably be worth it, but it's a shame it doesn't come out of the box.
git checkout for Remote Branches
$ git checkout --track origin/newsletter
Branch newsletter set up to track remote branch newsletter from origin.
Switched to a new branch 'newsletter'
Just
git branch
without options.
From the main page:
With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk.
No checkout of HEAD is performed after the clone is complete.
First clone the repo with the -n option, which suppresses the default checkout of all files, and the --depth 1 option, which means it only gets the most recent revision of each file
git clone -n git://path/to/the_repo.git --depth 1
Then check out just the file you want like so:
cd the_repo
git checkout HEAD name_of_file
How do I shallow clone a repo on a specific branch?https://stackoverflow.com/questions/21833870/how-do-i-shallow-clone-a-repo-on-a-specific-branch
To clone repo foo.git with branch bar do:
git clone --depth 1 https://path/to/repo/foo.git -b bar
https://stackoverflow.com/questions/31448445/git-log-show-one-commit-id-onlyhttps://git-scm.com/docs/pretty-formats
- '%H': commit hash
- '%h': abbreviated commit hash
https://emmanuelbernard.com/blog/2014/04/14/split-a-commit-in-two-with-git/
Interactive rebase
git rebase -i <oldsha1>
opens a list of commits from oldsha1 to the latest commit in the branch. You can:- reorder them,
- change the commit message of some,
- squash (merge) two commits together,
- and edit a commit.
We use edit in our case as we want to change the commit. Simply replace the
pick
word with edit
on the line of the commit you want to split. When you save and close this "file", you will be placed at that commit in the command line.Undo the actual commit
If you do a
git status
or a git diff
, you will see that git places you right after the commit. What we want is to undo the commit and place the changes in our working area.
This is what
git reset HEAD^
does: reset the state to the second last commit and leave the changes of the last commit in the working area. HEAD^
means the commit at HEAD
minus 1.
You can of course do that by using
git rebase -i
and most examples show how you can go back in time a couple of commits.git rebase -i HEAD^4 #go back 4 commits ago
There is a nicer and more efficient to do that when you work on topic branches
git rebase -i master
That's it. Pretty stupid but, since you can put any Git object reference, why not use the object where you started to fork off? The rebase will show you all commits between master and your branch.
javascript:Array.from(document.getElementsByClassName('outdated-comment')).forEach(l => l.classList.add('open'));
https://stackoverflow.com/questions/11369375/how-can-i-delete-all-of-my-git-stashes-at-oncegit stash clear
https://git-scm.com/docs/git-pull
Invoke an editor before committing successful mechanical merge to further edit the auto-generated merge message, so that the user can explain and justify the merge. The
--no-edit
option can be used to accept the auto-generated message (this is generally discouraged).https://stackoverflow.com/questions/7663451/view-a-specific-git-commit
git show <revhash>
https://coderwall.com/p/u4vjkw/git-add-interactive-or-how-to-make-amazing-commitsgit add --interactive
or git add -i
What now> p
staged unstaged path
1: unchanged +2/-0 [R]EADME
2: unchanged +4/-0 [i]ndex.html
Patch update>>
All the files with a star (*) at the left of the number will be processed.
To select the files, you have many possibilities:
- #: Select the file number #</li>
- -#: Unselect the file number #</li>
- *: Select all files</li>
- #-#: Select an interval of files</li>
- #-: Select the files from the # to the last</li>
Of course, all those notations can be mixed, for example, if you have 10 files changed, you can select this :
Patch update>> 1 3-6 8-
Which will select the 1, 3, 4, 5, 6, 8, 9 and 10
Stage this hunk [y,n,q,a,d,/,s,e,?]?
The more important are :
- y : yes</li>
- n : no</li>
- s : split, if the current diff can be splited in few smaller diffs</li>
- e : edit, to edit yourself the diff</li>
- q : to quit</li>
This fixed the issue for me:
- Open
Keychain Access
- Select
Keychains -> login
andCategory -> Passwords
- Type
github.com
in search box, you should see an entry (or entries) ofInternet Password
kind forgithub.com
. Right click & Delete them. - Go back to terminal and retry the git command that requires the password
- Type in your git username and password when prompted
You can use git rebase, for example, if you want to modify back to commit
bbc643cd
, run$ git rebase --interactive 'bbc643cd^'
In the default editor, modify
pick
to edit
in the line whose commit you want to modify. Make your changes and then commit them with the same message you had before:$ git commit --all --amend --no-edit
to modify the commit, and after that
$ git rebase --continue
to return back to the previous head commit.
WARNING: Note that this will change the SHA-1 of that commit as well as all children -- in other words, this rewrites the history from that point forward. You can break repos doing this if you push using the command
git push --force
ProTip™: Don't be afraid to experiment with "dangerous" commands that rewrite history* — Git doesn't delete your commits for 90 days by default; you can find them in the reflog:
$ git reset @~3 # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started
* Watch out for options like
* Also, don't rewrite history on any branches you're collaborating on.
http://jartto.wang/2018/07/08/git-commit/--hard
and --force
though — they can discard data.* Also, don't rewrite history on any branches you're collaborating on.
- type
- 用于说明
commit
的类别,只允许使用下面7个标识。
- 用于说明
- scope
- 用于说明
commit
影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
- 用于说明
- subject
- 是
commit
目的的简短描述,不超过50个字符。
- 是
# Wipes your unstaged changes
git checkout <filename or directory>
# Edit your X most recent commits interactively (squash, fixup, reword, drop)
git rebase -i HEAD~X
https://ma.ttias.be/pretty-git-log-in-one-line/
$ git log --pretty=oneline 3396763626316124388f76be662bd941df591118 Add twitter link c73bbc98b5f55e5a4dbfee8e0297e4e1652a0687 add facebook link
https://stackoverflow.com/questions/954560/how-does-git-handle-symbolic-links
$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0 symlink
$
The hash is a reference to the packed object that was created in the Git object store. You can examine this object if you look in
.git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c
.
The
120000
is the file mode. It would be something like 100644
for a regular file and is the mode special for links. From man git-config
:core.symlinksIf false, symbolic links are checked out as small plain files that contain the link text. git-update-index(1) and git-add(1) will not change the recorded type to regular file.
Use
git cat-file -p
to pretty-print the contents:$ git cat-file -p 1596f9db1
/Path/referenced/by/symlink
So, that's what Git does to a symbolic link: when you
git checkout
the symbolic link, you either get a text file with a reference to a full filesystem path, or a symlink, depending on configuration. The data referenced by the symlink is not stored in the repository.Symbolic links are a great way to simplify mundane tasks such as having the same configuration file in different folders
There is an important caveat when creating symlinks that are meant to be tracked under Git. The reference path of the source file should be relative to the repository, not absolute to the machine.
# Not good for Git repositories
ln -s /Users/gio/repo/foo.md ./bar/foo.md
# Good for Git repositories
cd ./bar && ln -s ../foo.md foo.md
The reason for this is that given that a symlink contains the path to the referenced file, if the path is relative to a specific machine the link won't work on others. If it's relative to the repository itself on the other hand, the OS will always be able to find the source.
https://stackoverflow.com/questions/3469741/remove-file-from-the-repository-but-keep-it-locallygit rm --cached -r somedir
Will stage the deletion of the directory, but doesn't touch anything on disk. This works also for a file, like:
git rm --cached -r somefile.ext
Afterwards you may want to add
somedir/
or somefile.ext
to your .gitignore
file so that git doesn't try to add it back.Undo a git add - remove files staged for a 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).
Try
git commit --amend --no-edit
.Skip Git Commit hooks
git commit --no-verify
-n
--no-verify
https://gist.github.com/metrofx/8951594
https://stackoverflow.com/questions/1628088/reset-local-repository-branch-to-be-just-like-remote-repository-head
Setting your branch to exactly match the remote branch can be done in two steps:
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).
# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced
However, if you run
git rebase
and hit a conflict, the process will stop and exit with a nonzero status. What you could do is check the exit status of the rebase operation, and, if it is nonzero, run git rebase --abort
to cancel the rebase:git rebase ... || git rebase --abort
git am
命令用于将一个 patch 文件,合并进入当前代码。
Github 对每个 PR 会自动生成一个 patch 文件。我们下载该文件,合并进本地代码,就可以在本地查看效果了。
$ curl -L http://github.com/cbeust/testng/pull/17.patch | git am
上面代码中,
curl
的-L
参数表示,如果有302跳转,curl
会自动跟进。后面网址里面的/cbeust/testng
是目标仓库,pull/17
表示该仓库收到的第17个 PR。
如果 PR 只包含一个 commit,那么也可以直接下载这个 commit 的 patch 文件。
$ curl https://github.com/sclasen/jcommander/commit/bd770141029f49bcfa2e0d6e6e6282b531e69179.patch | git am
五、cherry-pick
有时,PR 里面包含好几个 commit,但是你只想合并其中的一个或几个。
这时可以使用
cherry-pick
命令,挑出你感兴趣的 commit。https://stackoverflow.com/questions/15507264/can-i-specify-in-git-config-to-fetch-multiple-refspecs/15508750# 建立远程分支,追踪提交者的仓库 $ git remote add nullin git://github.com/nullin/testng.git # 从该远程仓库拉取代码 $ git fetch nullin # 只将感兴趣的 commit 加入当前代码 $ git cherry-pick commit1 $ git cherry-pick commit2 # 推送到自己的仓库 $ git push origin master
I do not want to fetch every branch from origin because there are many. I just want to track a few (e.g.,
master
) and my branches (organized under my_name
sub-directory). I can do the following:$ git fetch origin refs/heads/my_name/*:refs/remotes/origin/my_name/* refs/heads/master:refs/remotes/origin/master refs/heads/some_branch:refs/remotes/origin/some_branch
To overwrite the existing fetch refspec(s), without having to manually edit
.git/config
, you can use --unset-all
followed by as many --add
as needed.
For the example desired refspecs in the question, it would be:
$ git config --unset-all remote.origin.fetch
$ git config --add remote.origin.fetch +refs/heads/my_name/*:refs/remotes/origin/my_name/*
$ git config --add remote.origin.fetch +refs/heads/master:refs/remotes/origin/master
Then use
git config --get-all remote.origin.fetch
to verify the result.
been broken:
git config --get remote.origin.url
If referential integrity is intact:
git remote show origin
When using
git clone
(from GitHub, or any source repository for that matter) the default name for the source of the clone is "origin". Using git remote show
will display the information about this remote name. The first few lines should show:C:\Users\jaredpar\VsVim> git remote show origin
* remote origin
Fetch URL: git@github.com:jaredpar/VsVim.git
Push URL: git@github.com:jaredpar/VsVim.git
HEAD branch: master
Remote branches:
If you want to use the value in the script, you would use the first command listed in this answer
https://stackoverflow.com/questions/3999541/after-git-clone-i-do-not-see-my-branch
By default,
git clone
creates only one branch: the currently checked out one, generally master. However, it does create remote tracking branches for all other branches in the remote. Think of these as local copies of the remote's branches, which can be updated by fetching. They're not real local branches, as they're intended only as pointers to where the remote's branches are, not for you to work on.
If you run
git branch -a
you'll see all branches, local and remote. If you want to see just the remote ones, use git branch -r
. If you prefer a visual history display, try gitk --all
(or gitk --remotes
).
To create a local branch to work on, use
git branch <branch-name> origin/<branch-name>
https://stackoverflow.com/questions/520650/make-an-existing-git-branch-track-a-remote-branchgit 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
As of Git 1.7.0:
git branch --set-upstream foo upstream/foo
https://stackoverflow.com/questions/171550/find-out-which-remote-branch-a-local-branch-is-tracking
Find out which remote branch a local branch is tracking Ask Question
$ git branch -vv
main aaf02f0 [main/master: ahead 25] Some other commit
* master add0a03 [jdsumsion/master] Some commit
% git rev-parse --abbrev-ref --symbolic-full-name @{u}
origin/mainline
or
% git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
origin/mainline
git remote show origin
explicitly tells you which branches are tracking which remote branches. $ git remote show origin
* remote origin
Fetch URL: /home/ageorge/tmp/d/../exrepo/
Push URL: /home/ageorge/tmp/d/../exrepo/
HEAD branch (remote HEAD is ambiguous, may be one of the following):
abranch
master
Remote branches:
abranch tracked
master tracked
Local branches configured for 'git pull':
abranch merges with remote abranch
master merges with remote master
Local refs configured for 'git push':
abranch pushes to abranch (up to date)
master pushes to master (up to date)
git rev-parse
is an ancillary plumbing
command primarily used for manipulation.
One common usage of
git rev-parse
is to print the SHA1 hashes given a revision specifier. In addition, it has various options to format this output such as --short
for printing a shorter unique SHA1.
There are other use cases as well (in scripts and other tools built on top of git) that I've used for:
--verify
to verify that the specified object is a valid git object.--git-dir
for displaying the abs/relative path of the the.git
directory.- Checking if you're currently within a repository using
--is-inside-git-dir
or within a work-tree using--is-inside-work-tree
- Checking if the repo is a bare using
--is-bare-repository
- Printing SHA1 hashes of branches (
--branches
), tags (--tags
) and the refs can also be filtered based on the remote (using--remote
) --parse-opt
to normalize arguments in a script (kind of similar togetopt
) and print an output string that can be used witheval
Massage
just implies that it is possible to convert the info from one form into another i.e. a transformation command. These are some quick examples I can think of:- a branch or tag name into the commit's SHA1 it is pointing to so that it can be passed to a plumbing command which only accepts SHA1 values for the commit.
- a revision range
A..B
forgit log
orgit diff
into the equivalent arguments for the underlying plumbing command asB ^A
How can I find a file in my git repository with SourceTree? Ask Question
In the working copy view there is a dropdown where you can select a filter for the visible files in the column below. Just select "All Files" instead of the "Pending" default.
On the right side there also is a Searchbox to filter this file list.
https://help.github.com/articles/tracing-changes-in-a-file/
In a file or pull request, you can also use the menu to view Git blame for a selected line or range of lines.
https://stackoverflow.com/questions/278192/view-the-change-history-of-a-file-using-git-versioningchange in one file
You can use
git log -p filename
to let git generate the patches for each log entry.
https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history
To search for commit content (i.e., actual lines of source, as opposed to commit messages and the like), what you need to do is:
git grep <regexp> $(git rev-list --all)
Updates:
git rev-list --all | xargs git grep expression
will work if you run into an "Argument list too long" error
If you want to limit the search to some subtree (for instance "lib/util") you will need to pass that to the
rev-list
subcommand and grep
as well:git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util
This will grep through all your commit text for regexp.
The reason for passing the path in both commands is because
rev-list
will return the revisions list where all the changes to lib/util
happened, but also you need to pass to grep
so that it will only search on lib/util
.
Just imagine the following scenario:
https://stackoverflow.com/questions/5685007/making-git-log-ignore-changes-for-certain-pathsgrep
might find the same <regexp>
on other files which are contained in the same revision returned by rev-list
(even if there was no change to that file on that revision).
It is implemented now (git 1.9/2.0, Q1 2014) with the introduction pathspec magic
:(exclude)
and its short form :!
in commit ef79b1f and commit 1649612, by Nguyễn Thái Ngọc Duy (pclouds
).
You now can log everything except a sub-folder content:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Or you can exclude specific elements within that sub-folder
- a specific file:
git log -- . ":(exclude)sub/sub/file" git log -- . ":!sub/sub/file"
- any given file within
sub
:git log -- . ":(exclude)sub/*file" git log -- . ":!sub/*file" git log -- . ":(exclude,glob)sub/*/file"
You can make that exclusion case insensitive!
git log -- . ":(exclude,icase)SUB"
pathspec magic: add '
^
' as alias for '!
'The choice of '
!
' for a negative pathspec ends up not only not matching what we do for revisions, it's also a horrible character for shell expansion since it needs quoting.
So add '^
' as an alternative alias for an excluding pathspec entry.
https://stackoverflow.com/questions/67699/how-to-clone-all-remote-branches-in-git
$ git checkout -t origin/experimental
or the more verbose but easier to remember
$ git checkout --track origin/experimental
[master][~/notes-example]$ git notes add -m "Quick Note Test"
https://coderwall.com/p/7aymfa/please-oh-please-use-git-pull-rebase
When working on a project you usually synchronize your code by pulling it several times a day. What you might not know is that by typing
git pull
you actually issuing git fetch + git merge commands, which will result with an extra commit and ugly merge bubbles in your commit log (check out gitk to see them).
It's much better to use
git pull --rebase
to keep the repository clean, your commits always on top of the tree until you push them to a remote server. The command will apply all your yet-to-be-pushed commits on top of the remote tree commits allowing your commits to be straight in a row and without branches (easier git bisects, yay!).
Few notes though. If you want to merge a feature branch it might be wiser to actually merge your commits thus having a single point of integration of two distinct branches.
Also the conflict resolving will be now per commit basis, not everything-at-once, so you will have to use
git rebase --continue
to get to the next batch of conflicts (if you have any).
NOTE: Because of many discussions about this note. I DO NOT encourage rebasing remote (public or shared) branches. Rebasing local history is OK (it's more than OK, it's sometimes necessary to maintain a clean history), but changing other people commits history is considered a bad practice.
It's a lot easier to just set rebase as the default using
git config branch.autosetuprebase always
git tag --sort=-taggerdate
https://stackoverflow.com/questions/37724313/how-to-limit-number-of-returned-tags-in-git-tag-list
You can sort the tag list returned by
git tag
using --sort
option. The details are available on the manual page : git-tag.The default sorting is lexicographic.Prefix - to sort in descending order of the value.
Then, you could use
head
command to filter on wanted number. If needed, you can grep -v NOT_NEED_PATTERN
tag before getting the last 10 one.
Example
Assuming your tags increase numerically over version (e.g
1.0
, 1.1
, 2.0
, ...) , you can get 10 last tag with this commandgit tag --sort=-refname |head -n 10
git for-each-ref refs/tags/ --count=10 --sort=-refname --format="%(refname:short)"
https://harrow.io/blog/effortlessly-maintain-a-high-quality-change-log-with-little-known-git-tricks/
An annotated tag creates an additional tag object in the Git repository, which allows you to store information associated with the tag itself. This may include release notes, the meta-information about the release, and optionally a signature to verify the authenticity of the commit to which it points.
We can create a simple tag, based on the current repository's version, with:
$ git tag example
This creates a lightweight tag as a reference in
.git/refs/tags/example
, which points to the current commit. If we want to make it as an annotated tag, we need to supply -a
, and a message with -m
:$ git tag -a v1 -m "Version 1 release"
This will create an (unsigned) annotated tag object, containing that message and a pointer to the commit object. Now the reference in
.git/refs/tags/v1
will point to the tag object, which then points to the commit.
According to here [git-scm.org], you can use
git push <remote> refs/notes/*
to push all notes. Fetching can be done with
git fetch origin refs/notes/*:refs/notes/*
What's the difference between tags and branches? The workspace is (almost always) associated with a branch, called
master
by default. When it is, a commit will automatically update the master
reference to point to that new commit; in other words, branches are mutable references.
A tag, on the other hand, is created to point to a specific commit and thereafter does not change, even if the branch moves on. In other words, tags are immutable references.
http://alblue.bandlem.com/2011/04/git-tip-of-week-tags.html
Git provides a couple of mechanisms for identifying changes by labels instead of by unique hash values.
The first, we've already seen, is branches. When we switch between two branches, we're really using the descriptive label to identify a specific commit to switch to.
The second, which we'll introduce here, is tags. A tag is like a branch, in that it identifies a specific commit with a descriptive label.
https://stackoverflow.com/questions/2324195/how-to-get-tags-on-current-commit
For completion (thanks to Ciro Santili answer), git-tag has got the option --points-at that does exactly what Shawn is asking.
git tag -l --points-at HEAD
since it still comes in pretty high on google, I thought I'd add that this way works nicely:
git tag -l --contains HEAD
Or replace HEAD
with any other valid commit reference you like.
This will print a newline separated list of tags if the HEAD contains any tags, and print nothing otherwise, so you would get:
TAG6
TAG7
And of course there are lots of nice ways with various other shell tools that you can format that output once you have it...
Try this it will list all the tags along with annotations & 9 lines of message for every tag:
git tag -n9
can also use
git tag -l -n9
if specific tags are to list:
git tag -l -n9 v3.*
$ git for-each-ref --format '%(refname) %09 %(taggerdate) %(subject) %(taggeremail)' refs/tags --sort=taggerdate
https://www.quora.com/Git-revision-control-How-can-I-tag-a-specific-previous-commit-point-in-GitHub
To push a single tag:
git push origin <tag_name>
And the following command should push all tags (not recommended):
git push --tags
$ git tag -a v1.4 -m "my version 1.4"
Lightweight Tags
Another way to tag commits is with a lightweight tag. This is basically the commit checksum stored in a file — no other information is kept. To create a lightweight tag, don’t supply any of the -a
, -s
, or -m
options, just provide a tag name:
$ git tag -l "v1.8.5*"
https://git-scm.com/book/en/v2/Git-Tools-Submodules
It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.
Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.
$ git submodule add https://github.com/chaconinc/DbConnector
By default, submodules will add the subproject into a directory named the same as the repository, in this case “DbConnector”. You can add a different path at the end of the command if you want it to go elsewhere.