从其他分支拉取指定文件

git checkout [branch] -- [file name]

Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧-

%H | 提交对象(commit)的完整哈希字串 %h | 提交对象的简短哈希字串 %T | 树对象(tree)的完整哈希字串 %t | 树对象的简短哈希字串 %P | 父对象(parent)的完整哈希字串 %p | 父对象的简短哈希字串 %an | 作者(author)的名字 %ae | 作者的电子邮件地址 %ad | 作者修订日期(可以用 –date= 选项定制格式) %ar | 作者修订日期,按多久以前的方式显示 %cn | 提交者(committer)的名字 %ce | 提交者的电子邮件地址 %cd | 提交日期 %cr | 提交日期,按多久以前的方式显示 %s | 提交说明

git log 的常用选项

选项 说明
:# Git 操作技巧# Git 操作技巧 :# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧# Git 操作技巧–
-p 按补丁格式显示每个更新之间的差异。
–stat 显示每次更新的文件修改统计信息。
–shortstat 只显示 –stat 中最后的行数修改添加移除统计。
–name-only 仅在提交信息后显示已修改的文件清单。
–name-status 显示新增、修改、删除的文件清单。
–abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
–relative-date 使用较短的相对时间显示(比如,”2 weeks ago”)。
–graph 显示 ASCII 图形表示的分支合并历史。
–pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

限制输出长度

按照时间作限制的选项

$ git log --since=2.weeks

显示最近两周的提交

根据搜索条件列出符合的提交

使用 -S 选项过滤出删除或者添加了 function_name 的那些提交

$ git log -Sfunction_name

还可以给出若干搜索条件,列出符合的提交。 用 –author 选项显示指定作者的提交,用 –grep 选项搜索提交说明中的关键字。 (请注意,如果要得到同时满足这两个选项搜索条件的提交,就必须用 –all-match 选项。否则,满足任意一个条件的提交都会被匹配出来)

限制 git log 输出的选项:

选项 说明
:# Git 操作技巧# Git 操作技巧– :# Git 操作技巧# Git 操作技巧–
-(n) 仅显示最近的 n 条提交
–since, –after 仅显示指定时间之后的提交。
–until, –before 仅显示指定时间之前的提交。
–author 仅显示指定作者相关的提交。
–committer 仅显示指定提交者相关的提交。
–grep 仅显示含指定关键字的提交
-S 仅显示添加或移除了某个关键字的提交

Git 操作技巧

标签

列出所有标签

$ git tag

也可以匹配特定的标签:

$ git tag -l 'v1.1.*'

创建标签

有两种形式的标签:

  • 轻量标签
  • 附注标签

    附注标签

$ git tag -a v2.0.0 -m "version 2.0.0"

这里的 -m 同 commit 中一样,是为此标签添加说明信息,若没有添加 -m 选项的时候会弹出编辑器要求你输入说明信息。

完成之后就可以使用 git show v2.0.0 来查看与标签对应的提交信息了。

轻量标签

轻量标签不需要添加标签信息,可以使用下面的命令来打一个轻量标签:

$ git tag v2.1

后期打标签

可以对过去的某次提交打上标签,具体做法如下:

$ git tag -a v1.0.0 9fd67es

最后面跟的是某次提交的 hash 校验和。

共享标签

默认情况下,git push 命令不会将传送标签信息,如果要将标签信息推送至远程仓库,可以使用下面操作:

$ git push origin v1.0.0

如果有很多个标签需要推送,那么可以使用下面命令一次性全部推送至远程仓库:

$ git push origin --tags

回到特定标签的版本

如果希望工作目录回到某个特定标签的状态,可以使用下面操作:

$ git checkout -b version2 v2.0.0

这里的 -b 表示新建一个分支,而 version2 为新建的分支的名字,完成操作后分支 version2 中的内容就和 v2.0.0 标签所在位置一致了。这也就是用 v2.0.0 所在内容新建了一个分支。

列出某个 tag 的具体信息

$ git show v1.1

删除本地 tag

$ git tag -d <tag-name>

删除远程 tag

本地 tag 删除了以后,可以直接 git push origin --tag 来删除 tag

或者

$ git push origin --delete tag <tag-name>

Git 操作技巧

暂存(stash)

正在工作的时候,需要切换分支,但是手头的事情有不能立刻提交,这个时候可以首先保存下当前的状态,之后在某个合适的时候在恢复

执行存储

git stash

查看存储情况:

git stash list

恢复存储

git stash apply

这个命令会帮助你恢复到最近的一次存储

如果有多个存储,那么你需要指明:

git stash apply stash@2

删除存储

使用 apply 恢复后,存储还在,可以使用 drop 来删除

git stash drop stash stash@{0}

快速恢复

你可以使用 git stash pop 来重新应用存储,同时立刻将其从堆栈中删除

等同于:

git stash apply
git stash drop stash@0

从存储中创建分支

git stash branch newbranch

Git 操作技巧

gitignore 规则

.gitignore 的编写规则如下:

  • A blank line matches no files, so it can serve as a separator for readability.
  • A line starting with # serves as a comment. Put a backslash (\) in front of the first hash for patterns that begin with a hash.
  • Trailing spaces are ignored unless they are quoted with backslash (\).
  • An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. Put a backslash (\) in front of the first ! for patterns that begin with a literal !, for example, \!important!.txt.
  • If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git).
  • If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).
  • Otherwise, Git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, Documentation/*.html matches Documentation/git.html but not Documentation/ppc/ppc.html or tools/perf/Documentation/perf.html.
  • A leading slash matches the beginning of the pathname. For example, /*.c matches cat-file.c but not mozilla-sha1/sha1.c.
  • Two consecutive asterisks (**) in patterns matched against full pathname may have special meaning:
  • A leading ** followed by a slash means match in all directories. For example, **/foo matches file or directory foo anywhere, the same as pattern foo. **/foo/bar matches file or directory bar anywhere that is directly under directory foo.
  • A trailing /** matches everything inside. For example, abc/** matches all files inside directory abc, relative to the location of the .gitignore file, with infinite depth.
  • A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, a/**/b matches a/b, a/x/b, a/x/y/b and so on.
  • Other consecutive asterisks are considered invalid.

submodule

初始化 submodule

一个项目使用了 submodule 在 clone 下来后,需要执行 git submodule init 才能将 submodule 也 clone 下来。

安装 submodule

$ git submodule add <repository> <path>

克隆含有子模块的项目

执行了 git clone 之后并不会下载子模块,需要再次执行 git submodule init

# 克隆该项目
$ git clone https://github.com/user/repo

# 加载子模块
$ git submodule init

或者使用 --recursive 选项来进行 clone:

$ git clone --recursiv https://github.com/user/repo

更新 submodule

$ git submodule update --remote

push submodule

$ cd sub  # 进入子模块
$ git push  # 推送代码