Git 深入
一、git基础
1.查看文件状态
git status -s
添加-s
参数将会以简单的格式输出文件名列表
添加-v
参数将会显示文件的具体修改
M config/index.js
M config/prod.env.js
2..gitignore
文件格式
- 所有空行或者以
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式匹配。
- 匹配模式可以以(
/
)开头防止递归。 - 匹配模式可以以(
/
)结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(
!
)取反。
3.git diff
查看以暂存和未暂存修改
- 查看工作区未暂存的修改
git diff
- 查看暂存区的修改
git diff --cached
git diff --staged
4.文件的提交
- 跳过使用暂存区(直接提交当前工作区的修改)
git commit -a -m 'update'
5.移除文件
- 如果从工作区手动删除某个文件,执行提交后删除的文件会出现在
Changes not staged for commit:
下,如果要从git仓库中删除需要执行git rm
git rm fileName
- 强制删除
git rm -f fileName
6.关于移动文件
在git中移动文件可以执行
git mv oldFileName newFileName
此时git status
可以看到
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: oldFileName -> newFileName
其实,运行 git mv
就相当于运行了下面三条命令:
mv README.md README
git rm README.md
git add README
7.查看提交历史
- 默认
git log
会以时间顺序显示所有的更新
$ git log
commit c7b89b19bcdff982c850721ec310e80dad4092ab (HEAD -> master)
Author: Mario34 <1506747508@qq.com>
Date: Tue May 14 18:46:03 2019 +0800
t3
commit ab4e5675b37121f67e786a8504d1a1b9ef08b723
Author: Mario34 <1506747508@qq.com>
Date: Tue May 14 18:43:19 2019 +0800
t2
commit 7b97c7e4dec3fa08f8bc03da4354269028a70404
Author: Mario34 <1506747508@qq.com>
Date: Tue May 14 18:41:47 2019 +0800
first
-
git log -p -1
查询最近一次的文件更改
$ git log -p -1
commit 7b97c7e4dec3fa08f8bc03da4354269028a70404
Author: Mario34 <1506747508@qq.com>
Date: Tue May 14 18:41:47 2019 +0800
first
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..be78fa0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,57 @@
+# git命令深入
+
+
+
+#### 1.查看文件状态
+
+```bash
选项 | 说明 |
---|---|
-p |
按补丁格式显示每个更新之间的差异。 |
--online |
每次提交的检验码和提交备注 |
--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(后跟指定格式)。 |
-(n) |
仅显示最近的 n 条提交 |
--since , --after
|
仅显示指定时间之后的提交。 |
--until , --before
|
仅显示指定时间之前的提交。 |
--author |
仅显示指定作者相关的提交。 |
--committer |
仅显示指定提交者相关的提交。 |
--grep |
仅显示含指定关键字的提交 |
-S |
仅显示添加或移除了某个关键字的提交 |
8.撤销操作
-
撤销当前:如果在一次提交时提交信息出现填写错误,在未做任何修改的情况下执行
git commit --amend -m 'newCommit'
重新提交将会覆盖原来的提交信息
$ git commit -a -m 'test1'
[master 8044bf2] test1
1 file changed, 3 insertions(+), 1 deletion(-)
$ git commit --amend -m 'newCommit'
[master bfae5a2] newCommit
Date: Wed May 15 11:29:45 2019 +0800
1 file changed, 3 insertions(+), 1 deletion(-)
$ git log -2
commit bfae5a2918ce3ffbbb3b076fa8656d0c97c446a8 (HEAD -> master)
Author: Mario34 <1506747508@qq.com>
Date: Wed May 15 11:29:45 2019 +0800
newCommit
commit 9e582ae723cd6555811db8339b140050c0b44aec
Author: Mario34 <1506747508@qq.com>
Date: Wed May 15 11:25:09 2019 +0800
init
-
取消已经暂存的文件
当暂存区存在某个文件时提示
"git reset HEAD <file>..." to unstage
$ git status
On branch master
Changes to be committed:
("git reset HEAD <file>..." to unstage)
modified: README.md
使用git reset HEAD README.md
可以取消暂存,再次查看文件状态被修改的文件变成unstaged
状态
$ git reset HEAD README.md
Unstaged changes after reset:
M README.md
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
- 撤销文件修改
将文件还原成上次提交的状态,此操作将会将会丢失当前工作区的文件,并且不可回复,谨慎操作
9.远程仓库
-
查看远程仓库:运行
git remote
命令查看已经配置的远程仓库
$ git remote
origin
origin
是git给远程仓库的默认名字,同时也可以指定-v
显示远程仓库名对应的url
$ git remote -v
origin https://github.com/userName/demo.git (fetch)
origin https://github.com/userName/demo.git (push)
查看某一个远程仓库的更多信息,可以使用 git remote show [remote-name]
命令
$ git remote show origin
* remote origin
Fetch URL: https://github.com/userName/demo.git
Push URL: https://github.com/userName/demo.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
- 添加远程仓库:运行
git remote add <libraryName> <url>
$ git remote add test https://libraryUrl/demo/demo.git
$ git remote
origin
test
可以添加多个远程仓库,并且可以使用仓库对应的名称代替仓库地址
- 远程仓库中抓取与拉取
$ git fetch [remote-name]
这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
- 推送到远程仓库
git push [remote-name] [branch-name]
,下面是推送当前分支到远程的master
分支
$ git push origin master
- 远程仓库的移除与重命名:可以运行
git remote rename <oldName> <newName>
去修改一个远程仓库的简写名
$ git remote
origin
test
$ git remote rename test edited
$ git remote
edited
origin
- 可以使用
git remote rm
命令移除一个远程仓库
$ git remote
edited
origin
$ git remote rm edited
$git remote
origin
10.打标签
像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要。
- 查看所有标签
git tag
$ git tag
v0.1
v1.3$ git
- 创建附注标签:运行时指定
-a
选项
$ git tag -a v1.4 -m 'my version 1.4'
$ git tag
v0.1
v1.3
v1.4
-m
选项指定了一条将会存储在标签中的信息。
通过使用 git show
命令可以看到标签信息与对应的提交信息:
$ git show v1.4
tag v1.4
Tagger: Ben Straub <ben@straub.cc>
Date: Sat May 3 20:19:12 2014 -0700
my version 1.4
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
输出显示了打标签者的信息、打标签的日期时间、附注信息,然后显示具体的提交信息。
- 创建轻量标签
另一种给提交打标签的方式是使用轻量标签。 轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。 创建轻量标签,不需要使用 -a
、-s
或 -m
选项,只需要提供标签名字:
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5
这时,如果在标签上运行 git show
,你不会看到额外的标签信息。 命令只会显示出提交信息:
$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
changed the version number
- 补打标签
你也可以对过去的提交打标签。 假设提交历史是这样的:
$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
现在,假设在 v1.2 时你忘记给项目打标签,也就是在 “updated rakefile” 提交。 你可以在之后补上标签。 要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和):
$ git tag -a v1.2 9fceb02
可以看到你已经在那次提交上打上标签了:
$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5
$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 15:32:16 2009 -0800
version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date: Sun Apr 27 20:43:35 2008 -0700
updated rakefile
- 共享标签
默认情况下,
git push
命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。
运行 git push origin [tagname]
$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.5 -> v1.5
如果想要一次性推送很多标签,也可以使用带有 --tags
选项的 git push
命令。 这将会把所有不在远程仓库服务器上的标签全部传送到那里。
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.4 -> v1.4
* [new tag] v1.4-lw -> v1.4-lw
现在,当其他人从仓库中克隆或拉取,他们也能得到你的那些标签。
- 删除标签
要删除掉你本地仓库上的标签,可以使用命令 git tag -d <tagname>
。例如,可以使用下面的命令删除掉一个轻量级标签:
$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)
应该注意的是上述命令并不会从任何远程仓库中移除这个标签,你必须使用 git push <remote> :refs/tags/<tagname>
来更新你的远程仓库:
$ git push origin :refs/tags/v1.4-lw
To /git@github.com:schacon/simplegit.git
- [deleted] v1.4-lw
- 检出标签
如果你想查看某个标签所指向的文件版本,可以使用 git checkout
命令,虽然说这会使你的仓库处于“分离头指针(detacthed HEAD)”状态——这个状态有些不好的副作用:
$ git checkout 2.0.0
Note: checking out '2.0.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch>
HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final
$ git checkout 2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... add atlas.json and cover image
在“分离头指针”状态下,如果你做了某些更改然后提交它们,标签不会发生变化,但你的新提交将不属于任何分支,并且将无法访问,除非确切的提交哈希。因此,如果你需要进行更改——比如说你正在修复旧版本的错误——这通常需要创建一个新分支:
$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'
当然,如果在这之后又进行了一次提交,version2
分支会因为这个改动向前移动,version2
分支就会和 v2.0.0
标签稍微有些不同,这时就应该当心了。
11.git别名
- git 命令
下面自定义了两条git命令
$ git config --global alias.ci commit
$ git config --global alias.unstage 'reset HEAD --'
git ci 等价于 git commit
git unstage file等价于 git reset HEAD --file
- 外部命令
$ git config --global alias.visual '!gitk'
gitk 等价于 git visual
二、git 分支
有人把 Git 的分支模型称为它的`‘必杀技特性’',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。 理解和精通这一特性,你便会意识到 Git 是如此的强大而又独特,并且从此真正改变你的开发方式。
1.创建分支
执行git branch <branchName>
$ git branch test
$ git branch
* master
test
2.分支切换
注意:切换分支之前必须提交或暂存当前分支的更改,否则git将会禁止切换操作(避免文件丢失)
执行git checkout <branchName>
$ git checkout test
Switched to branch 'test'
3.分支的新建与合并
当在主master分支上发现了问题需要修改一般会在master分支的提交创建一个新的BUG分支,在BUG分支上修复完再合并到master,最后在提交到线上的仓库。
- 在主分支的问题HEAD创建一个新的bug分支并切换到该分支
$ git checkout master
Switched to branch 'master'
$ git checkout -b bug
Switched to a new branch 'bug'
- 修复完提交到
bug
到分支
$ git commit -a -m 'fix bug'
[master d7b96bd] fix bug
1 file changed, 7 insertions(+), 2 deletions(-)
- 切换到
master
分支将修改的bug
合并到master
分支上
$ git checkout master
Switched to branch master
$ git merge bug
Updating 08bc667..8c393f3
Fast-forward
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
-
遇到冲突时的分支合并需要手动解决后提交
-
删除
bug
分支
$ git branch -d bug
Deleted branch bug (was 08bc667).
4.分支管理
git branch
命令可以制定以下参数
参数 | 说明 |
---|---|
-v |
查看每一个分支的最后一次提交 |
--merged |
查看哪些分支已经合并到当前分支 |
--no-merged |
查看所有包含未合并工作的分支 |
5.远程分支
- 查看远程分支
$ git branch -a
- 推送当前分支的更新
$ git push origin master
- 跟踪分支
当克隆一个仓库时,它通常会自动地创建一个跟踪
origin/master
的master
分支。 然而,如果你愿意的话可以设置其他的跟踪分支 - 其他远程仓库上的跟踪分支,或者不跟踪master
分支。
运行 git checkout -b [branch] [remotename]/[branch]
,简化命令--track
$ git checkout --track origin/serverfix
如果跟踪的本地分支名与远程仓库的不同,使用原始的命令即可
$ git checkout -b sf origin/serverfix
- 拉取
$ git fecth
- 删除远程分支
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix
三、变基
在 Git 中整合来自不同分支的修改主要有两种方法:
merge
以及rebase
。
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
现在回到 master
分支,进行一次快进合并。
$ git checkout master
$ git merge experiment
请注意,无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
参考:Git - book https://www.git-scm.com/book/zh/v2