HEAD 的特殊用法
HEAD: 指向当前版本,最新的一个 commit 提交HEAD^ 或 HEAD~1 : 上一个版本(当前版本父版本)HEAD^^ 或 HEAD~2 : 上上一个版本
Commit Msg 提交规范
type:feat: 新功能fix: 修复 Bugdocs: 文档性质style: 代码格式refactor: 重构chore: 构建工具或者辅助工具变动
例如:
fix [影响范围]: 提交主题,整个提交的概要性说明(50 字节内)# 此处是一个空行提交的主体说明,72 字节,支持 md 语法。例如提交的是修复 bug:Bug 的现象是什么;什么时候引入的 Bug;之前为什么没有发现,什么条件下出现;如何解决的时候有其他方案# 签名区,记录提交的参与者、评审记录等# commit 指定 -s 参数自动添加签名Signed-off-by: Yang <...># 模板 1fix [影响范围]: 提交简短说明# 模板 2fix: 影响范围 [简短说明]
其他资料:
约定式提交规范
.gitignore 文件
指定了哪些文件应该被 Git 追踪(tracked,执行过 git add <文件>),已经被 Git 追踪的文件不受影响。
忽略原则:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的
.class文件; - 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
排除规则:https://git-scm.com/docs/gitignore#_pattern_format
TODO: 继续验证.gitignore 排除文件夹但包含特定的子文件夹
- 可选
!前缀,否定模式;先前模式排除的所有匹配的文件将再次被包含在内。如果排除了该文件的父目录,则无法重新包含该文件。
# 排除除 foo/bar 外,所有文件/*!/foo/foo/*!/foo/bar# 排除 dist 下所有文件,除了 dist/js 文件夹下以 jsplumb 开头的文件dist/*!dist/jsdist/js/*!dist/js/jsplumb*!dist/js/yui*

忽略成功后,在编辑其中相关的文件名颜色会变灰;文件变化时, git status 不再显示变化。
某个文件被忽略后,可以强制添加被忽略的文件
$ git add App.classThe following paths are ignored by one of your .gitignore files:App.classUse -f if you really want to add them.# 使用 -f 参数强制添加$ git add -f App.class
检查忽略文件的编写规则正不正确
$ git check-ignore -v App.class.gitignore:3:*.class App.class
pathspec 路径规范
Git 中的路径规范
git add
以文件、路径为基本单元
具体效果以实际为准,不同系统可能效果不同
# options 为参数,可选# [--] :指定路径,在某些场景下,需要加 -- 来标识后边跟的是路径;多个文件使用 空格隔开## git add -- index.js index.css# <pathspec> : 路径模式;支持大部分 glob 模式;$ git add [<options>] [--] <pathspec>...# . 代表当前文件夹下# * 是 (glob 路径模式)/(shell 通配符) 匹配$ git add . # 提交全部更改$ git add * # 追踪所有文件修改:不包括删除文件# 添加所有追踪的(该文件之前应执行过 add)、未追踪的更改(新文件)## -A, --all add changes from all tracked and untracked files$ git add -A# 提交已追踪的文件的修改# --update: update tracked files$ git add -u
以内容为基本单元
# -p 或 --patch(补丁): 分块提交# select hunks interactively 交互选择片段$ git add -p <file>Stage this hunk [y,n,q,a,d,/,e,?]? ny - stage this hunkn - do not stage this hunkq - quit; do not stage this hunk or any of the remaining onesa - stage this hunk and all later hunks in the filed - do not stage this hunk or any of the later hunks in the fileg - select a hunk to go to/ - search for a hunk matching the given regexj - leave this hunk undecided, see next undecided hunkJ - leave this hunk undecided, see next hunkk - leave this hunk undecided, see previous undecided hunkK - leave this hunk undecided, see previous hunks - split the current hunk into smaller hunkse - manually edit the current hunk? - print help
选择 s 分割更细粒度的块;使用 y 或 n 确定是否提交某个块
sourceTree 图形软件有此功能
如果直选中到文件:可以点击 暂存区块 之暂存 GIT 自动分好的区块
如果 GIT 自动区分好的区块依然太大,则可以选中需要提交的内容,点击暂存行;则只暂存选中的内容
git basic
可以二分搜索找到是哪一个特定的提交导致的 bug 或者 问题。
git branch
# 新建分支;## 新建分支还可以查看 git checkout -b <branchname> [<start-point>]## git branch [--track | --no-track] [-f] <branchname> [<start-point>]## 如果不提供 start-point 则在当前 HEAD 基础上新建;如果分支已存在可以使用 -f 强制覆盖$ git branch <branchname># 查看全部分支以及最新的 commit 信息$ git branch -v# 查看本地分支与远程分支的跟踪关联关系$ git branch -vvdev 54afbf4 [origin/dev] 优化排序的扩展都用冒泡和选择排序各自实现* master 25caf96 [origin/master] Merge branch 'master' of https://git.imooc.com/coding-315/leetcode# 查看远程分支$ git branch -r# 查看所有分支# * 是本地当前所在分支# -> : 远程 HEAD 指向的默认分支# -a, --all list both remote-tracking and local branches$ git branch -adev* masterremotes/origin/HEAD -> origin/devremotes/origin/devremotes/origin/masterremotes/origin/temp# 查看已经合并到当前分支上的分支$ git branch --merge# 本地分支重命名$ git branch -m <oldBranch> <newBranch># 删除远程分支$ git push --delete origin <oldBranch>
git commit
# 在命令行中指定 提交信息;信息长度有限制# -m, --message <message> commit message$ git commit -m "msg"# 多行信息提交:以单引号开始,单引号结束$ git commit -m 'msg Title>> msg body>'# 进入 vim 编辑界面编写 msg$ git commit# 指定文件路径:只提交部分文件$ git commit <filePath> -m "msg"# 修改最近的 commit 信息$ git commit --amend
Change to be commited: 要提交的更改
Changes not staged for commit: 不准备提交的更改
Untracked file:未跟踪的文件
详细命令
$ git commit -h ~/yaning/learnCode/learnGit/rep1usage: git commit [<options>] [--] <pathspec>...-q, --quiet suppress summary after successful commit-v, --verbose show diff in commit message templateCommit message options# 读取文件,用文件中的内容做 msg 提交# 如 git commit -e -F .git/COMMIT_EDITMSG-F, --file <file> read message from file--author <author> override author for commit--date <date> override date for commit-m, --message <message>commit message-c, --reedit-message <commit>reuse and edit message from specified commit-C, --reuse-message <commit>reuse message from specified commit--fixup <commit> use autosquash formatted message to fixup specified commit--squash <commit> use autosquash formatted message to squash specified commit--reset-author the commit is authored by me now (used with -C/-c/--amend)-s, --signoff add Signed-off-by:-t, --template <file>use specified template file-e, --edit force edit of commit--cleanup <mode> how to strip spaces and #comments from message--status include status in commit message template-S, --gpg-sign[=<key-id>]GPG sign commitCommit contents options-a, --all commit all changed files-i, --include add specified files to index for commit--interactive interactively add files-p, --patch interactively add changes-o, --only commit only specified files-n, --no-verify bypass pre-commit and commit-msg hooks--dry-run show what would be committed--short show status concisely--branch show branch information--ahead-behind compute full ahead/behind values--porcelain machine-readable output--long show status in long format (default)-z, --null terminate entries with NUL--amend amend previous commit--no-post-rewrite bypass post-rewrite hook-u, --untracked-files[=<mode>]show untracked files, optional modes: all, normal, no. (Default: all)
git checkout
检出命令。是一个危险的命令,因为他会重写工作区。
这个命令做的事情是将 HEAD 移到某个具体的提交上(分支名是有特殊含义的提交),然后更新工作目录。 由于这可能会覆盖本地的修改,Git 强制你提交或者缓存工作目录中的所有更改,不然在 Checkout 的时候这些就该都会丢失。
# 1. git checkout [-q] [<commit-id>] [--] [<filePath>]
## 不会改变 HEAD 头指针,用指定版本的文件覆盖工作区和暂存区中对应的文件
## 省略 commit-id 后,默认从暂存区即 index 中检出。检出命令主要是覆盖工作区。
# 2. git checkout [<branch>]
## 会改变 HEAD 头指针
## 省略 branch 会进入分离头指针状态,此状态的提交不能被引用关联,可能会丢失。
## 只有切换到分支才能对提交进行更新,所以主要作用是切换分支
# 3. git checkout [-m] [[-b | --orphan] <newBranch>] [startPoint]
## 创建和切换到新的分支,新的分支从指定的 startPoint 指定的提交开始创建默认是 HEAD
$ git checkout -b feature/model origin/feature/model
第一种跟第二种用法的区别在于:第一种命令种包含路径,为了避免 路径 与 引用或者提交 ID 重名而冲突,在路径名前加 -- 双加号以作分割。
# 以 HEAD 为 startPoint 新建分支 tmp
## 如果分支存在,则终止新建。并提示错误
$ git checkout -b tmp
fatal: A branch named 'tmp' already exists.
## 如果分支不存在,则新建成功并切换到新分支
$ git checkout -b tmp
Switched to a new branch 'tmp'
# 同上;如果分支存在,则强制覆盖 TODO: 待测试
$ git checkout -B tmp
以远程分支拉取代码
方法一:
# 以远程分支为基础新建分支
# 如果本地没有拉过代码(没有对应的远程分支)则需要先执行 git fetch
# 本地没有远程对应的分支时,会报
# fatal: ... is not a commit and a branch ... connot be created form it
$ git checkout -b <branch> origin/<branch>



方法二:
# 可以以本地没有的分支为基础新建分支;TODO:待测试
$ git checkout -b <branch> --track origin/<branch>
方法三:
# TODO: 待测试下边两种方式是否可行;
$ git checkout -b <branch> remotes/origin/<branch>
# 或者
$ git checkout -b <branch> refs/remotes/origin/<branch>
git cherry-pick
复制一个或者几个提交节点在当前分支做一次新的提交,避免重复劳动。

上图:
有两个分支,一个 topic 分支(最新提交为 3ba22 ),一个 master 分支(最新提交为 ed489 )。执行 git cherry-pick 2c33a 后,会将 topic 分支上的 2c33a 修改拷贝一份到当前工作区并自动执行commit生成新的提交 f142b 。
适用场景:
多版本共存项目中,出现了一个 Bug,v1.0 和 v2.0。
Bug 在某个分支上修复完成后不能直接简单的合并,这样会导致版本紊乱,但是又想同时应用这个修复的 Bug,又不想在每个分支重新修复一次。
TODO: 待测试
# 将 commit-id 做的更改在当前分支上重新做一次提交
$ git cherry-pick <commit-id>
# 批量 cherry-pick :start 时间早于 end 时间
# 左开右闭 不包含 start-commit
$ git cherry-pick <start-commit>..<end-commit>
# 闭区间 包含 start-commit
$ git cherry-pick <start-commit>^..<end-commit>
# 中间出现失败(遇到冲突)
## 解决完冲突后直接执行 --continue
$ git cherry-pick --continue
$ git cherry-pick --quit
## 不想继续,放弃执行 cherry-pick 命令
$ git cherry-pick --abort
git config
Git 的本地配置文件,存储对 Git 的一些参数设置。配置文件分为三个等级:本地(local)、用户(全局、—global)、系统(—system),权重依次减小。
系统文件:
全局文件:存储在用户家目录下
本地文件: .git/config
$ git config [option]
# 列出配置文件内容 --list 简写 -l
git config [--local | --global | --system] -l
# 编辑配置文件 --edit 简写 -e; 默认编辑 --local
git config [--local|--global|--system] -e
# 添加一条配置项
git config --global --add section.key value
git config --global section.key value
# 查看某个配置项的值 section.key 如 user.name
git config --global --get section.key
git config --global section.key
git clean
删除工作区中未被追踪的文件
# 测试运行,以便查看实际会删除那些文件和文件夹,以免误删
$ git clean -nd
# 强制删除多余的文件和文件夹
$ git clean -fd
git clone
默认情况下,git 会把本地 master 和 远程 master 对应起来,远程仓库的默认名为 origin;
克隆
master 为默认默认新建的分支;
最简命令
$ git clone <URL>
指定了拉取到本地的路径;
默认拉取的分支是 master
指定远程分支拉取代码
## 本地目录默认当前所在文件夹;目录名默认与远程一致
$ git clone <远程仓库地址> [<本地目录名>]
# 默认从指定远程分支 dev 克隆代码
# -b, --branch <branch>
# checkout <branch> instead of the remote's HEAD
$ git clone -b dev <url>
当克隆完毕后,进入项目中,会发现当前所处的分支是 dev;
git fetch
取回远程主机更新(其他人提交的 commit)。
# 取回某个远程主机上的所有分支的更新提交(对本地代码没有影响)
# 默认是 origin 主机
$ git fetch <远程主机>
# 取回特定分支的更新提交
$ git fetch <远程主机> <分支名>
取回的更新提交在本地主机上可以使用 远程主机名/分支名,origin/develop 的形式访问。git branch -r 列出远程分支, -a 参数查看所有分支。
取回远程主机更新后,才可以使用 checkout 在其基础像新建分支。
# 在远程 origin/master 的基础上新建分支
$ git checkout -b newBranch origin/master
# 使用 merge 或 rebase 合并远程分支上的提交
# 在当前分支上合并远程分支的提交
$ git merge origin/master
# 或者
$ git rebase origin/master
git diff
git 对差异比较进行了扩展,支持对二进制文件的差异比较。
git 的差异比较除了支持基于行的差异比较外,还支持一行内逐字比较
–word-diff
-w 忽略空白字符
不同提交之前的统计信息
# 查看不同版本之间的统计信息;
$ git diff --stat <commid-id> <commid-id2>
# 示例
assets/js/auditObject/historyProjectDetail.js | 10 ----
assets/js/auditObject/objectCommon.js | 1 -
assets/js/workBench/doubtList.js | 2 +-
pages/dataCenter/dataCollection.html | 376 ++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------
4 files changed, 93 insertions(+), 296 deletions(-)
# --numstat
# 类似于 --stat,但是会以十进制数字显示文件新增与删除的行数。如果是二进制文件,显示 - -
$ git diff --numstat <commid-id> <commid-id2>
# 示例
0 10 assets/js/auditObject/historyProjectDetail.js
0 1 assets/js/auditObject/objectCommon.js
1 1 assets/js/workBench/doubtList.js
92 284 pages/dataCenter/dataCollection.html
# --shortstat
# 只输出 --state 格式的最后一行,其中包含修改文件的总数以及添加和删除的行数
4 files changed, 93 insertions(+), 296 deletions(-)
# --name-only
# 只展示更改文件名
assets/js/auditObject/historyProjectDetail.js
assets/js/auditObject/objectCommon.js
assets/js/workBench/doubtList.js
pages/dataCenter/dataCollection.html
# --name-status
# 只展示更改文件名以文件修改状态
git —help
λ git --help
usage: git [--version] [--help] [-C <path>] [-c name=value]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
# 这些是各种情况下常用的 Git 命令
These are common Git commands used in various situations:
# 开始一个工作区(参阅:打开浏览器)
start a working area (see also: git help tutorial)
# 将一个仓库克隆到新的目录
clone Clone a repository into a new directory
# 创建一个空的 Git 仓库或者重新初始化现有仓库
init Create an empty Git repository or reinitialize an existing one
# 处理当前的更改(参阅:每天使用 Git 的一组最小命令集)
work on the current change (see also: git help everyday)
# 给文件内容添加索引(index, 或者叫 暂存区(stage))
add Add file contents to the index
# 移动或重命名文件,目录或者软连接
mv Move or rename a file, a directory, or a symlink
# 将当前 HEAD(指针) 重置到指定的 state 上
reset Reset current HEAD to the specified state
# 从工作树和索引中删除文件(add 之后的文件)
rm Remove files from the working tree and from the index
# 检查历史和状态(参阅:修订)
examine the history and state (see also: git help revisions)
bisect Use binary search to find the commit that introduced a bug
# 搜索版本库中的内容
grep Print lines matching a pattern
# 显示提交日志
log Show commit logs
# 显示各种类型对象的相关信息
show Show various types of objects
# 显示工作树状态(查看工作区和暂存区的文件状态)
status Show the working tree status
grow, mark and tweak your common history
branch List, create, or delete branches
checkout Switch branches or restore working tree files
commit Record changes to the repository
diff Show changes between commits, commit and working tree, etc
merge Join two or more development histories together
rebase Reapply commits on top of another base tip
tag Create, list, delete or verify a tag object signed with GPG
collaborate (see also: git help workflows)
fetch Download objects and refs from another repository
pull Fetch from and integrate with another repository or a local branch
push Update remote refs along with associated objects
'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
git init
# 初始化当前文件夹,被 git 管理
$ git init
# 创建一个新的文件夹,并初始化仓库
$ git init <dirName>
Initialized empty Git repository in /Users/<dirName>/.git/
git log
通过图形界面查看 commit 变化时间线、分支之间的关系。
通过自带的 gitk 命令在图形界面显示变化时间线。
查看提交历史(commit 的历史信息)
# --oneline: 在一行中显示 commit 的简略信息
# --pretty=oneline: 输出完成的 commit-id 值并在一行显示
# -5 或 -n5: 只显示前五个 commit
# --graph:在命令行显示分支简图
# --stat:显示每次 commit 的文件变化统计信息
# file1 | 3 +++
# 1 file changed, 3 insertions(+)
$ git log --oneline -n5[-5] --graph
# --decorate 打印所有提交的引用名称:里程碑或分支
# –-simplify-by-decoration:只显示被 branch 或 tag 引用的 commit
$ git log –-graph –-decorate –-oneline –-simplify-by-decoration –all
# 显示某个文件的版本历史,包括文件名修改
$ git log --follow <file>
# --author=<pattern> 按照作者过滤,引号内可以是正则表达式
# 作者是 Join 或者 YIBu 的提交
git log --author="Join\|YiBu"
* d8597d1 (HEAD -> fixhot/#3528-5) fix: 格式化文件
* 1e351ab (develop) Merge branch 'fixhot/#3528-5' into develop
|\
| * d91b8f4 fix: #3528-5-1 审计工作台 - 模型修改、模型新建、模型执行 bug
| * 6ff9372 fix: 格式化文件
* | 02fb482 (origin/develop) Merge branch 'fixhot/#3528-4.4.4.4.4' into develop
|\ \
=========
* 表示一个commit, 注意不要管*在哪一条主线上
| 表示分支前进
/ 表示分叉
\ 表示合入
对比分支之间的差异
# 查看 develop 上有而 master 上没有的提交
$ git log develop ^master --oneline
# 不知道谁提交的多,谁少;比较两个分支不同
## < 表示左边的分支
## > 表示右边的分支
$ git log master...dev --left-right --oneline
< 762da60 (master) master 提交新行
> cac171f (HEAD -> dev) 添加新行
> 7d1f584 修改 CSS
格式化打印信息
官方:git-log
博客:个性化你的 Git Log 输出格式
博客:git log 命令解析
# --abbrev-commit 好像很没啥用
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative

git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short --color

git log --color --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h%Creset %Cgreen(%cd) - %C(yellow)%d%Cblue %s %C(bold blue)<%an>%Creset' --author="Yi-Bu"

git log --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%Cred%h %Cgreen(%cd) %C(bold blue)<%an> %n - %C(yellow)%d%Cblue %s' --ancestry-path 67d96..9d4a6cd3

placeholder 占位符:
%n: 换行,新行
自带图形界面查看
可以像命令行一样使用不同参数调用
# 查看所有分支
$ gitk --all
# 显示两周以来的提交
$ gitk --since="2 weeks ago"
# 显示某个里程碑 v2.0 以来,针对某些目录和文件的提交
$ gitk v2.0.. <目录> <目录>
git pull
取回远程主机某个分支的代码并与本地指定分支合并。
# 完整命令
$ git pull <远程主机> <远程分支名>:<本地分支>
# 取出分支并与本地分支合并
## 如果与当前分支合并,冒号及其后边的分支可以省略
$ git pull origin master:dev
## 等同于
$ git fetch origin
$ git merge origin/next
# 远程分支(next)与当前分支合并
$ git pull origin next
# 当本地分支与远程某个分支具有追踪关系时,可以省略分支名
# 拉取并合并本地分支的远程追踪分支(remote-tracking branch)
$ git pull origin
# 如果当前分支只有一个追踪分支,分
git push
将本地更新推送到远程。
# 完整命令
$ git push <远程主机名> <本地分支名>:<远程分支名>
# 省略远程分支名;推送与之存在追踪关系的远程分支上(通常为同名分支),不存在则新建
$ git push origin master
# 当前分支在远程有存在追踪关系的分支
$ git push origin
# 省略本地分支名,表示删除远程分支(推送了一个空分支)
$ git push origin :master
# 等同
$ git push origin --delete master
git reset
重置,一般用于重置暂存区(除非使用 —hard 参数,否则不重置工作区。—hard 会破坏工作区未提交的改动)。
git reset 命令可以将 指针 HEAD 指向任何一个 commit-id,就像一个游标,并且更新暂存区为 commit-id 状态的目录树。
commit-id 的默认值是 HEAD。
使用 git reset 相当于丢弃历史记录,不能通过重置命令再找回丢失的历史)。
# 1. git reset [-q] [<commit-id>] [--] [filePath]
## 不会重置引用,也不会改变工作区(也可以说是重置到当前的 HEAD 引用)
## 而是用指定 commit-id 提交下的文件替换暂存区文件,如
$ git reset HEAD <filePaths> # 相当于取消 git add 后改变的暂存区
# 2. git reset [--soft | --hard | --mixed 等参数] [<commit-id>]
## 会重置引用,根据不同的选项可以对暂存区或者工作区进行重置
# 不同用法
## 使用 HEAD 指向的目录树重置暂存区,和引用(引用相当于未改变)
## 相当于 撤销 git add 后改变的暂存区
$ git reset [HEAD]
## 仅将 filePath 指定的文件撤出暂存区,其他文件不变
$ git reset -- <filePaths>
## 工作区和暂存区不变,但是引用指向上一次提交
## TODO: 虽然暂存区没有改变,但通过 git status 查看到上一次的提交的文件都成了 未提交 状态
$ git reset --soft HEAD^
## 默认;把 HEAD、暂存区修改为指定的 commit 的时候的状态,工作区不变
## 如果更改已经 add 但未 commit,则 add 后修改恢复到 add 前
$ git reset --mixed HEAD^
## 工作区、暂存区、引用(HEAD) 都会退到上一次提交的状态
$ git reset --hard HEAD^
备注:
## git commit --amend === 下边两条命令
$ git reset --soft HEAD^ && git commit -e -F .git/COMMIT_EDITMSG
git reflog
引用日志,或者 “reflogs”,记录当本地仓库中 分支和其他引用 更新时的提示
Reference logs, or “reflogs”, record when the tips of branches and other references were updated in the local repository
包括所有 commit 提交、已删除 commit 。只要 HEAD 发生变化都能记录。
记录的日志默认保存三个月
git rebase
变基、衍合。对提交进行变基操作,可以实现将指定范围内的提交“嫁接”到另外一个提交上。
#
# 变基遇到冲突后暂停,解决完冲突后(添加到暂存区,不提交)恢复变基操作的时候使用
$ git rebase --continue
# 遇到冲突后,跳过当前提交的时候使用
$ git rebase --skip
# 遇到冲突后终止当前操作,回到变基之前
$ git rebase --abort
git rebase -i 可以丢弃、修改、合并、重排提交。
git remote
管理远程主机(远程仓库);
# 默认 列出所有远程主机
$ git remote
origin
# -v : 查看远程主机信息
$ git remote -v
origin git@github.com:jquery/jquery.git (fetch)
origin git@github.com:jquery/jquery.git (push)
# 克隆的时候指定主机名: Jquery
$ git clone -o Jquery https://github.com/jquery/jquery.git
# 查看某个主机的详细信息
$ git remote show <主机名>
# 添加远程主机
$ git remote add <主机名> <网址>
# 删除
$ git remote rm <主机名>
# 重命名
$ git remote rename <原主机> <新主机>
git rm
# 删除某个文件
$ git rm <filePath>
# 只从暂存区移除,但本地保留
# only remove from the index
$ git rm --cached <filePath>
git stash 储藏
当想保存工作区及暂存区的状态时(修改状态),但又想回到一个干净的工作目录时使用。
WIP: Working in Process 工作区进度。
# 储藏当前没有 commit 的工作(变动):包括工作区、暂存区
## 没有任何参数的 git stash,相当于 git stash push
$ git stash
# 列出所有工作进度列表(储藏)
git stash list
# 删除 stash@{0} 的这一条储藏
git stash drop stash@{0}
git stash apply # 恢复
git stash apply stash@{0} # 恢复第 0 条 stash
git stash drop # 删除恢复的 stash
git stash pop # 恢复同时删除
# 删除所有存储的工作进度
$ git stash clear
储存当前工作区变动
# 给暂存添加说明
# 不推荐使用 git stash save TODO: 具体原因待查
## 新版本已经废弃此选项,取而代之的是 “stash push”;“save” 不能接收路径名
## 可以提供 -- <pathspec> 提供指定文件路径
$ git stash push -m "msg"
$ git stash push -m "新建 file 文件"
Saved working directory and index state On dev: 新建 file 文件
$ git stash list
stash@{0}: On dev: 新建 file 文件
# 展示 stash 详细信息;stasg@{0} 是一个死指针
$ git show --stat stash@{0}
commit 3851dd624383e7541f35d818a48dbb319c4f9361 (refs/stash)
Merge: 4dde1f5 6734fcc
Author: xxx <xxx@163.com>
Date: Wed Sep 18 14:10:16 2019 +0800
On dev: 新建 file 文件
file | 1 +
1 file changed, 1 insertion(+)
git tag
里程碑,人为的给 commit 命名
里程碑创建后,会在 .git/refs/tags 下生成一个引用文件,记录得是 tag 对象。
记录的是创建里程碑的用户(tagger)、创建里程碑的时间、以及为什么创建。
没有指定说明创建的是 轻量级里程碑、是一个 commit 对象
# 显示当前里程碑列表
$ git tag
# 列出标签及说明
$ git tag -n
# 模糊匹配里程碑
$ git tag -l "v2*"
# 创建标签
# commit-id 缺省默认指向当前 HEAD 指针
$ git tag <tagName> [<commit-id>]
# 创建带说明的标签
$ git tag -m "msg" <tagName>
# 删除 Tag
## 删除本地
$ git tag -d <tagName>
## 删除远程版本库里程碑
$ git push <remote_url> :<tagname>
## 删除远程 Tag
git push origin --delete tag <tagname>
# 共享里程碑: push 的时候需要明确的指出
$ git push origin tag1
# 一次性全部推送
$ git push origin --tags
## 或者
$ git push origin refs/tags/*
里程碑的推送必须显示推送(标明要推送哪个),是为了防止共享版本库里程碑泛滥
冲突现象
Git 用 <<<<<<< 、 ======= 、 >>>>>>> 标记出不同分支的内容
产生冲突的提示CONFLICT (content): Merge conflict in src/... src/… 文件内容产生冲突,自动合并失败
还可以同过执行 git status 查看
webstorm 显示冲突
冲突总结
根据合并操作是否遇到冲突,以及不同的冲突类型,可以分为以下几种类型:
- 成功的自动合并
- 逻辑冲突
- 真正的树冲突和树冲突
自动合并
自动合并的情况:修改了不同文件、修改相同文件的不同区域、文件重命名
修改不同文件
在远程操作用,如果两个用户分别在本地做了提交修改了不同的文件,当一个用户推送到服务器后,另一个用户推送的时候会遇到非快进式前进错误而被终止
此时需要先执行 git pull 更新共享仓库的提交并与当前分支合并后才能提交(合并为自动合并)。
修改相同文件的不同区域
同时修改文件名和文件内容
user1 修改文件名,并对内容作出修改;user2 修改文件内容。
结果是:自动合并,文件名修改,内容自动合并没有冲突
逻辑冲突
例如,如下两种场景:
===============
一个用户修改了一个文件的文件名,而另外的用户在其他文件中引用旧的文件名,这样的修改虽然可以合并成功但包含逻辑冲突;这个冲突会导致编译失败
一个用户修改了函数的返回值,而另外的用户使用旧的函数返回值并没有作相应的调整,虽然合并成功但存在逻辑冲突;这个冲突存在着潜在的 Bug
解决:
====
引入单元测试或者集成测试;
合并完成后对比合并前后版本修改的文件中,有没有自己要用的重点检查;检查公共文件资源。
修改公共文件后主动通知其他成员
树冲突
A 用户将 b 文件重命名为 c,B 用户将 b 文件重命名为 d;会造成一个树冲突
手动解决树冲突:A 与 B 商量出一个名字后修改
利用图形工具交互式解决树冲突
解决冲突
分支合并策略
快进模式 Fast-forward
这种提交简图:(master) $ git merge dev
合并前
合并后

使用 Faster-forward 模式,删除原来的分之后,会丢失分支信息。
使用 --no-ff 参数,强制禁用 Faster-forward 模式,使用普通模式合并,合并时会产生一个新的 commit ,这样就可以看出历史完整分支信息。

非快进合并
合并前


