基本操作:
csharp
Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 快照
1.git init:创建.git目录,目录文件尚未被跟踪,默认创建master分支,可以不连远程仓库,把git当作一个简单本地文件管理工具使用
2.git add xxx: 把xxx添加到暂存区,1.追踪新文件,2.暂存已修改的文件
3.git commit -m 'xxx':把暂存区内容提交到本地仓库,并添加提交说明信息
3.1.git commit:交互式添加提交说明信息
4.git clone xxx::克隆远程仓库
4.1 git clone xxx dirName:克隆远程仓库,使用dirName命名目标目录
5.git status:查看当前文件状态
5.1.git status -s(--short):-s是--short的简写,简洁的方式查看状态:输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区
的状态,??未追踪,A已暂存,M已修改
6.git diff:比较工作目录中当前文件和暂存区域快照之间的差异
6.1.git diff --staged:比较已暂存文件与最后一次提交的文件差异
6.2.注意:git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动
7.git rm xxx:从暂存区域移除xxx,移除后需要提交,注意工作目录下的文件也会被移除
7.1.git rm -f xxx:强制删除, 如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f
7.2.git rm --cached xxx:保留本地文件,从暂存区删除xxx
7.3.git rm log/\*.log:删除 log/ 目录下扩展名为 .log 的所有文件
7.4.git rm \*~:删除所有名字以 ~ 结尾的文件
8.git mv file_from file_to:文件重命名
8.1.本质是三条命令:1.mv file_from file_to 2.git rm file_from 3.git add file_to
9.git log:查看提交历史
9.1.git log -p -2:-p是--patch的简写,显示每次提交所引入的差异,-2显示最近两次提交
9.2.git log --stat:查看简略统计信息
9.3.git log --pretty=oneline:每个提交放在一行显示,git log --oneline也可以
9.4.git log --pretty=format:格式化输出
9.4.1.比如:git log --pretty=format:"%h %s" --graph:--graph以可视化的方式展示
9.4.2.git log --pretty=format常用选项:
%H:提交的完整哈希值,%h:提交的简写哈希值
%T:树的完整哈希值,%t:树的简写哈希值
%P:父提交的完整哈希值,%p:父提交的简写哈希值
%an:作者名字,%ae:作者的电子邮件地址,
%ad:作者修订日期(可以用 --date=选项 来定制格式)
%ar:作者修订日期,按多久以前的方式显示
%cn:提交者的名字,%ce:提交者的电子邮件地址
%cd:提交日期,%cr:提交日期(距今多长时间)
%s:提交说明
9.5.git log 的常用选项:
-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(用来定义自己的格式)。
--oneline:--pretty=oneline --abbrev-commit 合用的简写。
9.6.限制输出长度,限制 git log 输出的选项:
-<n>:仅显示最近的 n 条提交。
--since, --after:仅显示指定时间之后的提交。
--until, --before:仅显示指定时间之前的提交。
--author:仅显示作者匹配指定字符串的提交。
--committer:仅显示提交者匹配指定字符串的提交。
--grep:仅显示提交说明中包含指定字符串的提交。
-S:仅显示添加或删除内容匹配指定字符串的提交。
9.7.例子:查看 Junio Hamano 在 2008 年 10 月其间, 除了合并提交之外的哪一个提交修改了测试文件
git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
--before="2008-11-01" --no-merges -- t/
10.撤销操作
10.1.git commit --amend:用新的提交替换最后的提交
10.2.git restore --staged xxx 等于 git reset HEAD xxx:取消暂存的xxx文件
10.3.git restore xxx 等于 git checkout -- xxx:撤消对xxx文件的修改
10.3.1.git restore .:还原所有未提交的更改,包括工作目录和暂存区的更改
10.4.git reset:用于回退版本
10.4.0.git reset [--soft | --mixed | --hard] [HEAD]
--mixed:不删除工作空间改动代码,撤销commit,并且撤销git add . 操作这个为默认参数,
git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的
--soft:不删除工作空间改动代码,撤销commit,不撤销git add
--hard:删除工作空间改动代码,撤销commit,撤销git add,注意完成这个操作后,就恢复到了上一次的commit状态。
10.4.1.git reset [HEAD]:回退到上个版本,即取消暂存所有文件与修改,即回到最后一次commit的状态
10.4.2.git reset 052e:回退到指定版本
10.4.3.git reset HEAD^:回退到上个版本,就是最后一次commit之前的状态
10.4.4.git reset HEAD^ xxx:xxx回退到上个版本,就是最后一次commit之前的状态
10.4.5.git reset --hard HEAD:-hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,
并删除之前的所有信息提交,例如:
git reset --hard HEAD~3 # 回退上上上一个版本
git reset --hard bae128 # 回退到某个版本回退点之前的所有信息。
git reset --hard origin/master # 将本地的状态回退到和远程的一样
10.4.6.git reset --soft HEAD^:回退到上个版本,但保留文件更改的内容
HEAD 说明:
HEAD 表示当前版本
HEAD^ 上一个版本
HEAD^^ 上上一个版本
HEAD^^^ 上上上一个版本
以此类推...
可以使用 ~数字表示
HEAD~0 表示当前版本
HEAD~1 上一个版本
HEAD^2 上上一个版本
HEAD^3 上上上一个版本
以此类推...
10.4.7.如果使用reset回到之前的一个版本(或者说回退错了),但又想回到回退版本之前最新的版本:
1.使用 git reflog 命令查看Git的引用日志,找到你之前所在分支的历史记录。你会看到所有的提交和操作记录。
2.针对你要恢复的提交,找到其对应的提交哈希值。
3.运行以下命令来恢复到该提交:
git reset --hard xxxx:xxxx是对应版本的哈希值
11.远程仓库的使用
11.1.git remote:列出你指定的每一个远程服务器的简写
11.2.git remote -v:显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL
11.3.git remote add shortname url:添加远程仓库,同时指定一个方便使用的简写
11.4.git fetch shortname:拉取shortname仓库的数据,git fetch 命令只会将数据下载到你的本地仓库------它并不会自动合并或
修改你当前的工作
11.5.git push origin master:将 master 分支推送到 origin 服务器
11.6.git remote show origin:查看某个远程仓库
11.7.git remote rename oldname newname:修改一个远程仓库的简写名
11.8.git remote remove xxx:移除一个远程仓库
12.打标签
12.1.git tag -l:列出已有的标签,-l是--list的简写,按照通配符列出标签需要 -l 或 --list 选项
12.2.git tag -a v1.0 -m 'version 1.0':-a创建附注标签,-m添加提交信息
附注标签:包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息
12.3.git tag v1.0:创建轻量标签
12.4.git show v1.0:查看标签信息和与之对应的提交信息
12.5.git tag -a v1.0 9fceb02:对过去的提交打标签,命令的末尾指定提交的校验和(或部分校验和)
12.6.git push origin v1.0:共享标签,推送标签到共享服务器
12.7.git push origin --tags:一次性推送很多标签
12.8.git tag -d v1.0:删除掉你本地仓库上的标签
12.9.git push origin --delete v1.0:删除远程标签
12.10.git checkout v1.0:检出标签,查看某个标签所指向的文件版本,会使你的仓库处于"分离头指针(detached HEAD)"
的状态------这个状态有些不好的副作用,如果你需要进行更改,比如你要修复旧版本中的错误,那么通常需要创建一个新分支:
git checkout -b version1 v1.0
13.git别名
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
当要输入 git commit 时,只需要输入 git ci
git config --global alias.unstage 'reset HEAD --'
这会使下面的两个命令等价:
git unstage fileA
git reset HEAD -- fileA
git config --global alias.last 'log -1 HEAD'
轻松地看到最后一次提交:
git last
Git 只是简单地将别名替换为对应的命令
你可能想要执行外部命令,而不是一个 Git 子命令。 如果是那样的话,可以在命令前面加入 ! 符号
git config --global alias.visual '!gitk'
分支详情看:这里
csharp
14.分支
每次提交时都会生成一个提交对象,提交对象里有一个指针指向一个树对象,树对象里存储文件对象的指针,指向文件快照
Git的分支,本质是指向提交对象的可变指针,
Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。
master 分支会在每次提交时自动向前移动。
由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。
创建一个新分支就相当于往一个文件中写入 41 个字节(40 个字符和 1 个换行符),如此的简单能不快吗?
14.1.git branch:列出当前所有分支,*表示当前所在分支
14.1.1.git branch -v:查看每一个分支的最后一次提交
14.1.2.git branch --merged:查看哪些分支已经合并到当前分支,可以删除已合并的分支
14.1.3.git branch --no-merged:查看哪些分支未合并到当前分支
14.1.4.git branch --no-merged master:不用切换到master分支,查看未合并到master分支的有哪些
14.1.5.git branch -d branchName:删除本地分支
14.2.git branch branchName:创建分支branchName
14.3.git checkout branchName:切换分支branchName,HEAD就指向切换后的分支,HEAD就是当前本地操作的分支
14.4.git checkout -b branchName:创建并切换分支branchName
14.5.git log --oneline --decorate:查看各个分支当前所指的对象
14.6.git log --oneline --decorate --graph --all:查看项目分叉历史
14.7.git merge branchName:把branchName分支合并到当前所在分支
14.8.合并分支发生冲突时,只需修改冲突的文件,再按照正常流程走一遍即可:1.add添加到暂存区,2.commit提交的本地仓库
冲突发生后,使用git status查看文件状态
csharp
远程引用是对远程仓库的引用(指针),包括分支、标签等等
远程跟踪分支是远程分支状态的引用。它们是你无法移动的本地引用。一旦你进行了网络通信,
Git 就会为你移动它们以精确反映远程仓库的状态。请将它们看做书签, 这样可以提醒你该分支在远程仓库中的位置
就是你最后一次连接到它们的位置
15.1.git push origin dev:把本地的dev分支推送到远程仓库(origin)的dev分支
Git自动将dev分支名字展开为:refs/heads/dev:refs/heads/dev,等价git push origin dev:dev
15.2.git push origin dev:dev2:把本地的dev分支推送到远程仓库的dev2分支上
15.3.git config --global credential.helper cache:解决HTTPS URL推送每次输入密码
15.4.git fetch origin:当抓取到新的远程跟踪分支时,本地不会自动生成一份可编辑的副本,就是说,本地不会有一个新的分支
例如:远程仓库别人新推送了一个分支dev2,你本地没有dev2,运行git fetch origin后,本地不会不会新增一个dev2的分支,
只有一个不可以修改的origin/dev2指针。可以运行git merge origin/dev2将这些工作合并到当前分支, 如果想要在自己的
dev2分支上工作,可以将其建立在远程跟踪分支之上:git checkout -b dev2 origin/dev2,这会给你一个用于工作的本地分支,
并且起点位于 origin/dev2
15.5.git checkout --track origin/dev2 等价于 git checkout -b dev2 origin/dev2
15.6.git checkout dev2:切换分支,如果远程仓库有之匹配名字的远程分支,本地没有,会直接创建本地分支dev2,并跟踪远程分支
origin/dev2
15.7.git branch -u origin/dev2:修改正在跟踪的上游分支为dev2,-u是--set-upstream-to缩写
15.8.git branch -vv:查看设置的所有跟踪分支
15.9.git pull:拉去数据到本地仓库,然后合并到工作目录
15.10.git fetch:拉去数据到本地仓库
15.11.git push origin --delete dev:删除远程分支dev
csharp
分支变基主要用于改变提交历史,让人更容易阅读,有利有弊
贮藏与清理 :
当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是 git stash 命令
csharp
16.1.git stash 或 git stash push:现在想要切换分支,但是还不想要提交之前的工作;所以贮藏修改,将新的贮藏推送到栈上
16.2.git stash list:查看贮藏
16.3.git stash apply:恢复贮藏的工作,之前暂存的文件状态会变为未暂存
16.4.git stash apply --index:尝试重新应用暂存的修改,文件状态和之前保持一致
16.5.git stash drop stash@{0}:按贮藏的名字移除贮藏,git stash list会列出贮藏名字
16.6.git stash --keep-index:不仅要贮藏所有已暂存的内容,同时还要将它们保留在索引中
16.7.git stash -u:-u简写--include-untracked,贮藏未跟踪文件
16.8.git stash --patch:不会贮藏所有修改过的任何东西,交互式地提示哪些改动想要贮藏、哪些改动需要保存在工作目录中
16.9.git stash branch newbranch:从贮藏创建一个分支
16.10.git clean:移除没有忽略的未跟踪文件
16.11.git clean -d -n:只是想要看看它会做什么,将要移除什么,先运行这个命令,看看
16.12.git clean -f -d:命令来移除工作目录中所有未追踪的文件以及空的子目录,使用它需要 Git 配置变量 clean.requireForce
没有显式设置为 false。