###一、看图说话:
-
下面是git的工作原理图
-
三种状态
- 已提交(committed)、已修改(modified)和已暂存(staged)
-
三个工作区域的概念
-
Git 仓库、工作目录、暂存区域
-
Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
-
工作目录是对项目的某个版本独立提取出来的内容。 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。
-
暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中。 有时候也被称作“索引”,不过一般说法还是叫暂存区域。
-
-
解释说明
Workspace:工作区
指的是在PC中能看得到的创建的一个管理仓库的目录,比如我的 ‘存放代码文件夹’ 就是一个工作区,工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Index / Stage:暂存区
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。执行git add .
Repository:仓库区(或本地仓库)
执行git commit
Remote:远程仓库
###二、基础配置
-
Git的设置文件为
.gitconfig
,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。# 显示当前的Git配置 $ git config --list # 编辑Git配置文件[两个都可以] $ vim ~/.gitconfig $ git config -e --global # 设置提交代码时的用户信息 $ git config --global user.name "[name]" $ git config --global user.email "[email address]"
-
注意
1)如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息
2)当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global 选项的命令来配置
3) 输入 git config <key>: 来检查 Git 的某一项配置 $ git config user.name
-
git config --list
user.name=John Doe user.email=johndoe@example.com color.status=auto color.branch=auto color.interactive=auto color.diff=auto ...
-
编辑Git配置文件 $
vim ~/.gitconfig
编辑Git配置文件时,会出现如下样式,如果我们要编辑,这需要按 i 键,进入编辑模式,编辑完成时,则需要输入 esc 键,在输入":wq"退出[core] excludesfile = /Users/xxx/.gitignore_global [difftool "sourcetree"] cmd = opendiff \"$LOCAL\" \"$REMOTE\" path = [mergetool "sourcetree"] cmd = /private/var/folders/46/n897p0cd2cggv2lbm01jwvf40000gp/T/AppTranslocation/BE014DBD-44EE-4208-BC41-804AB54D9917/d/SourceTree.app/Contents/Resources/opendiff-w.sh \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" trustExitCode = true [user] name = xxxxx email = xxxx@qq.com [http "https://github.com"] ~
###三、git 基础
-
配置并初始化一个仓库(repository)、开始或停止跟踪(track)文件、暂存(stage)或提交(commit)更改
-
3.1 初始化仓库
第一种是在现有项目或目录下导入所有文件到 Git 中; 第二种是从一个服务器克隆一个现有的 Git 仓库。如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入
$ git init
-
3.2 克隆
$ git clone [url]
//默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来,会在当前目录下创建一个名为 “libgit2” 的目录 git clone xxxx //如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以使用如下命令: //在本地创建的仓库名字变为 mineFileName。 git clone xxx mineFileName
- 3.3 记录每次更新到仓库
工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。
- 检查当前文件状态
$ git status
- 创建一个新的 README 文件:在当前目录下
$ echo > README
;如果之前并不存在这个文件,使用 git status 命令,你将看到一个新的未跟踪文件:
$ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
- 跟踪新文件;使用命令 git add 开始跟踪一个文件。 所以,要跟踪 README 文件,运行:
//git add (files) 命令,开始跟踪当前目录下的文件。 git add 命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。 //这个命令理解为“添加内容到下一次提交中”而不是“将一个文件添加到项目中”要更加合适 $ git add README //此时再运行 git status 命令,会看到 README 文件已被跟踪,并处于暂存状态:
- 忽略文件,一个名为
.gitignore
的文件
//在当前目录下执行:如下命令,则会创建一个名为 .gitignore 的文件 vim .gitignore //列出要忽略的文件模式 *.[oa] *~ 第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此
更多请去 gitHub 了解
- 想知道具体修改了什么地方,可以用
$ git diff
命令
更多如下:
若要查看已暂存的将要添加到下次提交里的内容 git diff --cached 对Git 1.6.1 及更高版本还允许使用 git diff --staged,效果是相同的,但更好记些。) git diff --staged
请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。
- 提交更新
$ git commit
//commit 命令后添加 -m 选项,将提交信息与命令放在同一行 git commit -m "提交信息" //跳过使用暂存区域;只要在提交的时候,给 git commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤 git commit -a -m "提交信息"
- 移除文件
$ git rm
注意:如果删除之前修改过并且已经放到暂存区域(索引)的话,则必须要用强制删除选项 -f(译注:即 force 的首字母)
我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加 .gitignore 文件,不小心把一个很大的日志文件或一堆 .a 这样的编译生成文件添加到暂存区时, 这一做法尤其有用。 为达到这一目的,使用 --cached 选项: $ git rm --cached README //给定前导目录名称时,允许递归删除 git rm -r --cached [xxx] //示例:删除pod目录下的忽略文件 $ git rm -r --cached Pods/
- 移动文件
//要在 Git 中对文件改名,可以这么做: $ git mv file_from file_to
-
-
3.4 查看提交历史
$ git log //一个常用的选项是 -p,用来显示每次提交的内容差异。 //你也可以加上 -2 来仅显示最近两次提交: $ git log -p -2 //如果你想看到每次提交的简略的统计信息,你可以使用 --stat 选项: $ git log --stat
-
3.5 撤消操作
- 撤消操作
//有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令尝试重新提交 $ git commit --amend //你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作: $ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend 最终你只会有一个提交——第二次提交将代替第一次提交的结果。
-
取消暂存的文件,
$ git reset HEAD <file>...
注意:该命令只会取消 已经执行git add 的文件
-
撤消对文件的修改,
$ git checkout -- <file>...
-
3.6远程仓库的使用
- 查看远程仓库
$ git remote //它会列出你指定的每一个远程服务器的简写 //可以指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。 $ git remote -v
- 添加远程仓库
//格式:添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写: git remote add <shortname> <url> //示例 $ git remote add pb https://github.com/paulboone/ticgit
- 从远程仓库中抓取与拉取
//格式:这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。 $ git fetch [remote-name]
注意:
如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写
,
所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch 命令会将数据拉取到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作
- 推送到远程仓库
//格式:
git push [remote-name] [branch-name]
//示例:当你想要将 master 分支推送到 origin 服务器时
$ git push origin master
- 查看某个远程仓库
//格式:
git remote show [remote-name]
- 远程仓库的移除与重命名
//运行 git remote rename 去修改一个远程仓库的简写名
// 例如,想要将 pb 重命名为 paul,
$ git remote rename pb Paul
$ git remote
origin
Paul
//如果因为一些原因想要移除一个远程仓库——你已经从服务器上搬走了或不再想使用某一个特定的镜像了,又或者某一个贡献者不再贡献了——可以使用 git remote rm
$ git remote rm Paul
$ git remote
origin
-
3.7 打标签
- 列出标签
$ git tag
$ git tag v0.1 v1.3
- 创建标签: 主要类型的标签
轻量标签(lightweight)与附注标签(annotated)
附注标签
:在运行 tag 命令时指定 -a 选项,-m 选项指定了一条将会存储在标签中的信息$ git tag -a v1.0 -m "my version 1.4" //git show 命令可以看到标签信息与对应的提交信息 $ git show v1.0
轻量标签
:轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息$ git tag v1.4-lw $ git tag v0.1 v1.3 v1.4 v1.4-lw v1.5
- 删除标签:
git tag -d <tagname>
$ git tag -d v1.0.1 Deleted tag 'v1.0.1' (was b356cdd) //必须使用 git push <remote> :refs/tags/<tagname> 来更新你的远程仓库: $ git push origin :refs/tags/v1.0 remote: Powered by GITEE.COM [GNK-3.8] remote: warning: Deleting a non-existent ref. To https://xxxx.git - [deleted] v1.0
- 列出标签
-
3.8 Git 别名
git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名//当要输入 git commit 时,只需要输入 git ci。 随 $ git config --global alias.ci commit
-
3.8 打标签
###四、git 分支
-
4.1 分支的新建与合并
- 新建
# 新建一个分支,但依然停留在当前分支 $ git branch [branch-name] //新建一个分支并同时切换到该个分支上,该命令相当于执行git branch [branch-name] && git checkout [branch-name] $ git checkout -b [branch-name]
- 合并分支
git merge
执行合并命令后,在执行git status,注意到了
"ahead of "
这个词$ git status On branch dev Your branch is ahead of 'origin/dev' by 5 commits. (use "git push" to publish your local commits)
- 遇到冲突时的分支合并
在合并冲突后的任意时刻使用 git status 命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件
如果修改同一个文件,冲突一般如下:
<<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> iss53:index.html // 解释:冲突格式 <<<<<<< HEAD:index.html 上半部分内容 (运行 merge 命令的时候,就已经存在的内容) ======= 中间用这个隔开 下半部分内容 (需要合并的内容) >>>>>>> iss53:index.html
解决方案
这表示 HEAD 所指示的版本(也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支);为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内容。
在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决 -
4.2 分支管理
- git branch
//注意 master 分支前的 * 字符:它代表现在检出的那一个分支(也就是说,当前 HEAD 指针所指向的分支)。 这 $ git branch * dev master //如果需要查看每一个分支的最后一次提交,可以运行 git branch -v 命令 $ git branch -v * dev 826fea8 测试分支dev1.1 master cef0ea0 Merge branch 'dev' //--merged 与 --no-merged 这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。 如果要查看哪些分支已经合并到当前分支,可以运行 git branch --merged: $ git branch --merged $ git branch --no-merged //删除分支 $ git branch -d testing
-
4.3 分支开发工作流
开发过程中一般操作:长期分支、特性分支 -
4.4 远程分支
- 远程跟踪分支是远程分支状态的引用,以
(remote)/(branch)
形式命名,可以执行git branch -a
命令查看命名形式
$ git remote origin $ git remote -v origin https://gitee.com/multiApp/MineApp.git (fetch) origin https://gitee.com/multiApp/MineApp.git (push) $ git branch -a * dev master remotes/origin/dev remotes/origin/master
注意:
"origin" 并无特殊含义 远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一样。 同时 “master” 是当你运行 git init 时默认的起始分支名字,原因仅仅是它的广泛使用,“origin” 是当你运行 git clone 时默认的远程仓库名字。 如果你运行 git clone -o booyah,那么你默认的远程分支名字将会是 booyah/master。
- 推送,格式:
git push (remote) (branch):
# 删除远程分支 $ git push origin --delete [branch-name] $ git branch -dr [remote/branch] # 新建远程分支:把新建的本地分支push到远程服务器,远程分支与本地分支同名(当然可以随意起名) //可以通过这种格式来推送本地分支到一个命名不相同的远程分支 $ git push origin 本地分支:远程分支
- 跟踪分支
当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。 然而,如果你愿意的话可以设置其他的跟踪分支,或是一个在其他远程仓库上的跟踪分支,又或者不跟踪 master 分支。
//格式:git checkout -b [branch] [remotename]/[branch] $ git checkout --track origin/serverfix //如果想要将本地分支与远程分支设置为不同名字,你可以轻松地使用上一个命令增加一个不同名字的本地分支: $ git checkout -b sf origin/serverfix //设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,你可以在任意时间使用 -u 或 --set-upstream-to 选项运行 git branch 来显式地设置。 $ git branch -u origin/serverfix Branch serverfix set up to track remote branch serverfix from origin. //查看设置的所有跟踪分支,可以使用 git branch 的 -vv 选项。 $ git branch -vv * dev 826fea8 [origin/dev] 测试分支dev1.1 master cef0ea0 [origin/master] Merge branch 'dev'
-
拉取
git fetch: 命令从服务器上抓取本地没有的数据
git pull : 含义是一个 git fetch 紧接着一个 git merge 命令 -
删除远程分支
$ git push origin --delete serverfix To https://github.com/schacon/simplegit - [deleted] serverfix
- 远程跟踪分支是远程分支状态的引用,以
-
4.5 分支变基
在 Git 中整合来自不同分支的修改主要有两种方法:merge
以及rebase
参考
使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样
-
如下图:分支dev 上 再新建了一个分支,这两个分支并均做出了修改
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1S85ebAy-1586502868808)(https://upload-images.jianshu.io/upload_images/1683932-f55199a1b5037628.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)] -
如果通过
git merge
来合并分支,则会出现一个交叉现象,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6sKGoIu7-1586502868808)(https://upload-images.jianshu.io/upload_images/1683932-b5126da8f92dad4e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
通过gitsourcetree 上查看,如下图:
- 通过
git rebase
合并代码
$ git checkout test2.0 Switched to branch 'test2.0' $ git rebase dev First, rewinding head to replay your work on top of it... Applying: test2.0 分支
-
-
上述命令的原理:
1)首先找到这两个分支[也就是当前分支 test2.0 以及变基操作的目标基底分支 dev] 共同的祖先 C2
2)然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底 C3
3)最后以此将之前另存为临时文件的内容修改依序应用
如下图: 不会产生交叉
现在回到 dev 分支,进行一次快进合并。
$ git checkout dev Switched to branch 'dev' Your branch is ahead of 'origin/dev' by 2 commits. (use "git push" to publish your local commits) $ git status On branch dev Your branch is ahead of 'origin/dev' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean $ git merge test2.0 Updating bc13dcf..48a6f53 Fast-forward MineApp/MineApp/SceneDelegate.m | 2 ++ 1 file changed, 2 insertions(+)
如下图:一条直线
4)总结
这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。5)变基的风险
不要对在你的仓库外有副本的分支执行变基。
###其他相关命令
- 添加与删除
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p
# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...
# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]
# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]
- 代码提交
# 提交暂存区到仓库区
$ git commit -m [message]
# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a
# 提交时显示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
- 分支
# 列出所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
# 新建一个分支,并切换到该分支
$ git checkout -b [branch]
# 新建一个分支,指向指定commit
$ git branch [branch] [commit]
# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
例如: git branch --track lockBranch origin/DEV
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
# 切换到上一个分支
$ git checkout -
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream-to=origin/远程分支的名字 本地分支的名字
# 合并指定分支到当前分支
$ git merge [branch]
# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]
# 删除分支
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
# 新建远程分支:把新建的本地分支push到远程服务器,远程分支与本地分支同名(当然可以随意起名)
$ git push origin 本地分支:远程分支
- 标签
# 列出所有tag
$ git tag
# 新建一个tag在当前commit
$ git tag [tag]
# 新建一个tag在指定commit
$ git tag [tag] [commit]
# 删除本地tag
$ git tag -d [tag]
# 删除远程tag
$ git push origin :refs/tags/[tagName]
# 查看tag信息
$ git show [tag]
# 提交指定tag
$ git push [remote] [tag]
# 提交所有tag
$ git push [remote] --tags
# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]
- 查看信息
# 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]
# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s
# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次diff
$ git log -p [file]
# 显示过去5次提交
$ git log -5 --pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
- 远程同步
# 下载远程仓库的所有变动
$ git fetch [remote]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
- 撤销
# 恢复暂存区的指定文件到工作区
$ git checkout [file]
# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit] [file]
# 恢复暂存区的所有文件到工作区
$ git checkout .
# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]
# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard
# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]
# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]
# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]
# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]
# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop
- 解读
比如:修改 README.md 文件,用git status 命令来查看
MajqdeiMac:majqTest majq$ git status
On branch master
Your branch is up to date with ‘origin/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”)
-
上面标注颜色的文本意思是:
git add 更新将提交的内容
git checkout – 丢弃工作区中的文件更改) -
1)解读 git checkout [file]
git checkout -- README.md
分为两种情况:
第一种
: 修改 README.md 文件后,还没有添加暂存区(也就是还没有使用git add 命令),使用该命令,则撤销修改就会到跟修改前版本库一模一样(也就是没有修改 README.md文件那个状态)
第二种
:修改 README.md 文件后,已经添加暂存区(也就是已经使用git add 命令,把修改添加到暂存区了)然后又对README.md文件进行修改,现在,撤销修改就回到添加到暂存区后的状态(修改readme.txt,并且git add,然后又修改了readme.txt, 此时执行git checkout,回到git add 后的状态) -
2)解读 git reset [file]
需求 ,现在我git add之后,但是我还想放弃git add,回到上一次git commit的状态,怎么办? (就是说撤销掉暂存区,回到工作区的状态)
分两步执行:
场景1
:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout – file。
场景2
:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
命令如下:
MajqdeiMac:majqTest majq$ `git status`
On branch master
Your branch is up to date with 'origin/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")
MajqdeiMac:majqTest majq$ `git add .`
MajqdeiMac:majqTest majq$ `git status`
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
`(use "git reset HEAD <file>..." to unstage)`
modified: README.md
MajqdeiMac:majqTest majq$ `git reset HEAD README.md`
Unstaged changes after reset:
M README.md
MajqdeiMac:majqTest majq$ `git checkout -- README.md`
MajqdeiMac:majqTest majq$ `git status`
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
###十、其他
# 生成一个可供发布的压缩包
$ git archive
文章参考: http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
重点参考: https://www.git-scm.com/book/zh/v2