Git 的基本使用
文章目录
- Git 的基本使用
- 一、初始化一个仓库
- 二、状态转换和基本操作
- 2.1 `git add`, 使文件处于“暂存”状态
- 2.2 修改一个已被跟踪的文件,使文件处于“已修改”状态
- 2.3 修改一个已暂存文件,使暂存区和非暂存区同时出现文件名相同的文件
- 2.4 `git commit` 提交更新,使文件处于已更新状态
- 2.5 `git commit -a `对已跟踪过的文件暂存起来一并提交,从而跳过了`git add`步骤
- 2.6 `git rm` 从git上移除某个文件
- 2.7 `git mv` 对文件进行改名
- 2.8 撤销操作
- 2.9 远程仓库的使用
- 2.10 标签
- 三、查看状态和提交历史
- 3.1 `git status`
- 3.2 `git status -s` 简化版
- 3.3 `git diff` 查看快照之间的差异
- 3.4 `git diffftool` 使用通过图像化的方式
- 3.5 `git log` 查看提交历史
- 四、忽略文件
- 五、分支
- 5.1 创建分支`git branch testing`
- 5.2 切换分支`git checkout testing`
- 5.3 查看项目分叉的图
- 5.4 创建一个新的分支,同时切换到新的分支上
- 5.5 合并分支`git merge`
- 5.6 删除分支
- 5.7 查看分支列表
- 5.8 查看每一支分支最后一次提交
- 六、远程分支
一、初始化一个仓库
1.1 git init
1.2 git clone
git支持多种数据传输协议,比如:http、https、ssh
以ssh的方式克隆一个git仓库
git clone [email protected]:/home/hef/dev/git_wp/gittestwp.git
二、状态转换和基本操作
2.1 git add
, 使文件处于“暂存”状态
git add
命令使用文件或目录的路径作为参数;如果参数是目录路径,该命令将递归地跟踪该目录下的所有文件。
git add
有三个用途:(添加内容到下一次提交中)
- 可以用它开始跟踪新文件;
- 或者把已跟踪的文件放入暂存区;
- 还能用于合并时把有冲突的文件标记为已解决状态;
2.2 修改一个已被跟踪的文件,使文件处于“已修改”状态
2.3 修改一个已暂存文件,使暂存区和非暂存区同时出现文件名相同的文件
2.4 git commit
提交更新,使文件处于已更新状态
git commit -v
显示更详细的修改内容提示;
git commit -m "message"
将提交信息和命令放到同一行;
2.5 git commit -a
对已跟踪过的文件暂存起来一并提交,从而跳过了git add
步骤
2.6 git rm
从git上移除某个文件
git rm
后面可以跟文件或目录的名字,也可以使用glob模式
例如:删除所有以~结尾的文件:
git rm \*~
例如:删除log目录下,拓展名为.log
的文件
git rm log/*.log
第一种情况:文件处于被跟踪状态,并且未被修改
执行git rm
命令,将文件从已跟踪的文件清单中移除,并连带从工作目录中删除指定文件。
第二种情况:文件处于修改状态,并且已经放入到缓存区,必须使用git rm -f
进行强制删除
这种情况,数据不能被恢复。
第三种情况:希望将文件从Git仓库移除(亦即从暂存区移除),但仍然希望保留在当前工作目录中。换句话说,想将文件保留在磁盘,但是不想让Git继续跟踪。比如,忘了添加.gitignore
文件,不小心将很大一堆日志文件添加到暂存区中。
git rm -cached README
2.7 git mv
对文件进行改名
git mv README README.md
上面的命令相当于下面三条命令:
mv README README.md
git rm README
git add README.md
2.8 撤销操作
任何你为提交的东西,丢失了,很可能再也找不回来
1) 修改提交信息 git commit --amend
情况一:刚提交了,发现提交的信息写错了,可以运行git commit --amend
命令尝试重新提交
此时快照保持不变,修改的只是提交信息
情况二:发现忘记了暂存某些需要的修改,可以像下面这样,将两次提交合并成一次提交:
git commit -m “inital commit”
git add forgotten_file
git commit --amend
2) 取消暂存状态 git reset
3) 撤销对文件的修改 git checkout
2.9 远程仓库的使用
-
查看远程仓库:
git remote -v
-
添加远程仓库:
git remote add
-
从远程仓库中获取数据:
git fetch [remote-name]
git fetch
命令会将数据拉取到你的本地仓库,但它并不会自动合并或修改你当前的工作。当准备好是,你必须手动将其合并入你的工作 -
git pull
命令自动抓取,然后河滨远程分支到当前分支 -
推送到远程仓库:
git push <remote-name> <branch-name>
(1)只有当你有所克隆服务器到写入权限,并且之前没有人推送过时,这条命令才会生效
(2)当你和其他人在同一时间克隆,他们先推送到上游,你的推送将会毫无疑问地被拒绝。你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送
-
查看远程仓库的详细信息:
git remote show origin
-
远程仓库的重命名:
git remote rename ph paul
-
移除远程仓库:
git remote rm paul
2.10 标签
(1) 列出标签:git tag
这个命令会以字母顺序列出标签,但是它们出现的顺序并不重要。
(2)创建标签:轻量标签和辅助标签
通常建议创建辅助标签
轻量标签更像一个不会改变的分支。辅助标签是存储在Git数据库中的一个完整对象(包含了打标签者的名字、电子邮件地址、日期时间)。
创建一个辅助标签:git tag -a v1.0 -m "first version"
创建一个轻量标签:git tag v1.0
(3) 查看标签信息与对应的提交信息:git show v1.0
(4)后期打标签(在末尾加上校验和)
git tag -a v1.1 9fceb02
####(5)共享标签
- 共享一个标签:
git push origin [tagname]
- 一次共享很多标签:
git push origin --tags
,这个命令会将所有不在远程仓库服务器上的标签全部传送到那里
(6)删除标签
git tab -d v1.4
上面的命令并不会从任何远程仓库中移除这个标签,必须使用git push origin :refs/tags/<tagname>
来更新你的远程仓库,如:
git push origin :refs/tags/v1.4
?(7)检出标签(不理解)
git checkout v1.0
出现的副作用:使仓库处于“分离头指针”的状态
三、查看状态和提交历史
3.1 git status
这个命令可以看出:
- 当前所在的分支;
- 所对应的远程分支;
- 文件的状态;
3.2 git status -s
简化版
??
:表示新添加的文件未被放入暂存区;
A
:表示新添加暂存区的文件;
右M
:表示文件被修改了还没有被放入暂存区;
左M
:表示文件被修改了并且已经放入暂存区;
MM
:表示被修改的文件放入了暂存区,并且又被修改了,因此该文件在暂存区和工作区都有该文件被修改的记录;
3.3 git diff
查看快照之间的差异
(1)直接输入git diff
,查看当前工作目录和暂存区域快照之间的差异
直接输入git diff
, 此命令比较多是工作目录中当前工作目录和缓存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容;
(2)输入git diff --cached
或者git diff --staged
(1.6.1 以上的版本允许),查看已暂存的将要添加到下次提交里的内容
3.4 git diffftool
使用通过图像化的方式
3.5 git log
查看提交历史
-
git log -p
一个常用的选项是-p
,用于显示每次提交的内容差异git log -p
-
git log -p -2
用于显示最近两次提交的内容差异 -
git log --stat
用于显示每次提交的简略信息git log --stat
-
git log --oneline
或git log --pretty=oneline
将提交历史在一行中显示 -
git log --pretty=short
展示信息较少 -
git log --pretty=full
展示较全面的信息 -
git log --pretty=fuller
展示更全面信息 -
git log --pretty
以默认的形式展示信息 -
git log --pretty=format:"%h - %an - %ar : %s"
-
当format或oneline与log的另一个选项
--graph
结合的时候,会以更形象的方式展示出来
git log
常用的选项:
选项 | 说明 |
---|---|
-p | 按照补丁格式显示每个更新之间的差异 |
–stat | 显示每次更新的文件修改统计信息 |
–shortstat | 只显示--stat 最后一行的统计信息 |
–name-only | 仅在提交信息后面显示已修改的文件清单 |
–name-statue | 显示新增、修改、删除的文件清单 |
–abbrev-commit | 仅显示SHA-1的前几个字符,而非所有的40个字符 |
–relative-date | 使用较短的相对时间来显示 |
–graph | 显示ASCLL图形表示的分支合并历史 |
–pretty | 使用其他格式显示历史提交信息,可用的选项包括:oneline、short、full、fuller、format(后面跟指定的格式) |
git log
按照时间做限制的选项:--until
或--since
git log
用于筛选的选项--S
, 列出添加或移除某些字符串的提交,例如:git log -Stest_s
,查找在提交中添加或删除了“test_s”字符串的提交记录;
查看某些文件或目录的提交历史:git log -- log --
四、忽略文件
要养成一开始就设置好.gitignore
文件的习惯,以避免误提交这类无用的文件
对于不要纳入Git管理的文件(这些文件都是自动生成的),例如:日志文件、或者编译过程中创建的临时文件。在这种情况下,可以创建一个名为:.gitignore
的文件,列出要忽略的文件模式。
.gitignore
格式规范:
-
所有空行或者以
#
开头的行都会被git忽略; -
可以使用标准的glob模式匹配(所谓glob模式是指shell所使用的简化了的正则表达式);
*
匹配零个或多个任意字符;- 使用两个
*
表示匹配任意中间目录,如:a/**/z 可以匹配a/b/z,也可以匹配a/b/q/z; - [abc] 匹配任意一个列在方括号中的字符,这个例子中,要么匹配一个a,要么匹配一个b,要么匹配一个c;
- 在方括号中使用短划线分割两个字符,表示所有在这两个字符范围内的都可以匹配,比如:[a-c],表示匹配所有0到9点数字;
- 问号
?
只匹配一个任意字符;
-
匹配模式可以以(/)开头防止递归;
-
匹配模式可以以(/)结尾指定目录;
-
要忽略指定模式以为的文件或目录,可以在模式前加
!
取反;
忽略文件配置参考:
https://github.com/github/gitignore
五、分支
git分支的本质:仅仅是指向提交对象的可变指针。
5.1 创建分支git branch testing
Git怎么知道当前在哪个分支上?
Git有个HEAD
的特殊指针,指向当前所在的本地分支。
5.2 切换分支git checkout testing
分支的切换,会改变你的工作目录的文件
当你切换分支的时候,GIT会重置你的工作目录
5.3 查看项目分叉的图
git log --oneline --decorate --all --graph
5.4 创建一个新的分支,同时切换到新的分支上
git checkout -b iss53
上面这条命令是下面两条命令的缩写:
git branch iss53
git checkout iss53
5.5 合并分支git merge
git checkout master
git merge hotfix
合并情况一:快进(fast-forward)
当试图合并两个分支时,如果顺着一个分支走下去,能到达另一个分支,那么git在合并两者的时候,只会简单的将指针向前推进。这种情况下,合并操作没有要解决的分歧——这就叫“快进(fast-forward)”。
合并情况二:一次合并提交
特别之处:它不止一个父提交。
Git会自行决定选取哪一个提交作为最优的共同祖先。
合并情况三:冲突时发生冲突
如果在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改。合并分支的时候,会出现冲突。
使用git status
命令,可以查看那些因包含冲突,而处于未合并(uncommit)状态的文件。
5.6 删除分支
git branch -d hot fix
5.7 查看分支列表
git branch
5.8 查看每一支分支最后一次提交
git branch -v
5.9 查看哪些分支已经合并(或还没有合并)到当前分支
git branch --merged
上面列出的分支,中可以将不带*号的删除掉(git branch -d),因为已经合并了,可以安全地删除。
git branch --no-merged
如果要强制删除那些还未合并的分支信息,可以执行:-D
六、远程分支
远程跟踪分支是远程分支状态的引用,它们是你不能移动的本地引用。
当你做任何网络通信操作时,它们会自动移动
它们以(remote)/(branch)命名
远程仓库的名字origin,并无实际意义,默认为origin。可以通过git clone -o myorigin ..
重命名
6.1 查看远程分支的信息
git ls-remote
git remote show
6.2 推送git push origin serverfix
一条被简化的命令
语法:git push <remote> <branch>
Git自动将serverfix
分支名字展开为:refs/heads/serverfix:refs/heads/serverfix
。
可以运行:git push origin serverifx:serverifx
做同样的事情。
可以运行:git push origin serverifx:awesomebranch
,将本地的serverifx分支数据推送到远程仓库上的awesomebranch分支。
避免每次输入密码,可以设置:git config --global credential.helper cache
6.3 在本地创建一个起点为远程分支指针所指位置的指针
git checkout -b serverfix origin/master
现在分支 serverfix 会自动从origin/master 上拉取。(这句话不理解)
快速创建一个以远程分支指针所指位置为起点的分支:
git checkout --track origin/master
6.4 查看所有的跟踪分支git branch -vv
运行这个命令可以查看:
- 每个分支正在跟踪远程的哪个分支;
- 本地分支和远程分支对比,是落后、领先、还是都有;
注意:这个命令并没有连接服务器,只会告诉你本地缓存的服务器数据。想要获取最新数字,需运行:
git fetch --all; git branch -vv
6.5 git fetch
与git pull
的区别:
git fetch
只会从远程拉取数据,不会修改工作目录的内容。它只会获取数据,然后让你自己合并;
git pull
在大多数情况下,它的含义是git fetch
,之后再执行git merge
;
6.6 删除远程分支git push origin --delete servfix
6.7 分支–变基rebase
变基的作用:合并分支。
变基合并分支的过程:就好像将提交到某一分支上的所有修改都移至另一个分支上,就好像“重新播放”一样。
回顾用“三方合并”的过程:
git checkout master
git merge servfix master
使用变基操作进行合并分支:
git checkout servfix
git rebase master
再回到master分支上进行一次快速合并:
git checkout master
git merge servifx
变基使提交历史更加简洁。经过变基的历史记录,尽管实际开发工作是并行的,但它们看上去就像串行一样,提交历史是一条直线,没有分叉。
变基是将一系列提交按照原有次序应用到另一个分支上,而合并是将最终结果何在一起
(1) 有趣的变基操作:截取特性分支上的一个特性分支,然后变基到其他分支;
git rebase --onto master server client
上面这句话的意思:取出client分支,找出client分支和server分支的共同祖先之后的修改,然后将它们在master分支上重放一遍。
6.8 变基的风险:不要对在你的仓库外有副本的分支执行变基
假如在那些已经被推送至共有仓库的提交上执行变基命令,并因此丢弃了一些别人的开发所基于的提交,那麻烦就大了。
如果你或你的同事在某些情形下决意要这么做,请一定要通知每个人执行
git pull --rebase
命令,这样尽管不能避免伤痛,但能有所缓解。
git pull --rebase 等同于 git fetch,再git rebase teamone/master
总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史,从不对已推送至别处的提交执行变基操作,这样,你才能享受到两种方式带来的便利