git工作区-暂存区-版本库关系
- 工作区:就是你在电脑里能看到的目录。
- 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。
图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
操作命令:
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached
" 命令时,会直接从暂存区删除文件,工作区则不做出改变。 当执行 "git checkout ." 或者 "git checkout --
" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。 当执行 "git checkout HEAD ." 或者 "git checkout HEAD
" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
git init
$ mkdir runoob $ cd runoob/ $ git init
用 git init 在目录中创建新的 Git 仓库
git clone
git clone [url]
使用 git clone 拷贝一个 Git 仓库到本地,让自己能够查看该项目,或者进行修改。
ls
ls命令 显示自己创建的所有文件
ls -a 显示文件夹下的文件(包括git init生成的文件)
git add
git add [filename] 提交工作区某个文件
git add test.txt 添加工作区中test.txt文件
git add . 提交工作区中所有文件
此时会提交工作区中所有的文件
git status
git status 显示完整的暂存区的状态
git status -s 显示简介的暂存区的状态,以获得简短的结果输出
touch 命令
touch a.txt 增加a.txt文件
git config命令
Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地址。
git config --global user.name 'runoob' 添加名字为runoob
git config --global user.email test@runoob.com 添加邮箱为test@runoob.com
git commit
git commit -m '第一次版本提交' 将内容从暂存区提交到版本库并添加注释
-m 选项以在命令行中提供提交注释
git commit -am '修改 z.txt 文件' 将已经commit过且又修改了的内容从工作区直接添加到版本库并添加注释
仅适用于提交(commit)过,在本地又修改了的文件
git reset Head
git reset Head
将暂存区的所有内容取消,跟工作区一致
git reset Head a.txt
将暂存区的a.txt移除
git reset 版本号
git reset 版本号
将版本库中的状态回退到某个版本
上图中c3fb493版本提交了z.txt的变更
使用命令 git reset 2fb4090将版本库回退到上一个版本
此时暂存区中没有add z.txt文件, 只有工作区中的变动
git rm
git rm --cached a.txt
把文件从暂存区域移除,但保留在当前工作目录中,仅是从跟踪清单中删除
git rm -f [filename]
删除提交过,在工作区修改了,add到暂存区的文件,工作区和暂存区中都删除
git rm [filename]
删除提交过,但是此时没有在暂存区中的文件
- git rm不能删除没有跟踪的文件,不能删除已经跟踪且工作区修改的文件
- git rm能删除已经跟踪且工作区未修改的文件
git rm –r *
可以递归删除,进入某个目录中,执行此语句,会删除该目录下的所有文件和子目录
git checkout HEAD
会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
git checkout HEAD [filename] 将HEAD中的单个文件替换
git checkout HEAD . 将HEAD中的全部文件替换
上面图片中的操作,将本地工作区中删除的z.txt文件重新恢复回本地工作区,但是恢复回来的文件只能是提交过的z.txt内容,至于删除前z.txt已经修改但是没有提交的内容就会丢失了
git checkout
会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
git checkout . 将暂存区中的所有内容覆盖工作区
git checkout [filename] 将暂存区中指定文件覆盖工作区的文件
git mv
git mv 命令用于移动或重命名一个文件、目录、软连接。
git mv z.txt z.txtt 将z.txt重命名为z.txtt
利用git mv进行重命名
git branch
git branch 列出所有分支
git branch [branch name] 新建分支
在哪个分支下创建新的分支,创建出来的新的分支就是复制当前分支
git checkout [branch name] 切换分支
git checkout -b [branchname] 创建新分支并立即切换到该分支下
git branch -d [branchname] 删除分支
如果处于需要被删除的分支,此时执行删除此分支,删除不了.需要位于被删除分支以外才能被删除.
多个分支共用工作区和暂存区,如果在deve工作区增加zzz文件,master中也会增加zzz文件,master中将zzz提交到暂存区,然后切换到deve中,查看的话,deve中zzz也被添加到了暂存区,在deve中将zzz提交commit到版本库,此时切换到master,master工作区和暂存区中的zzz文件消失
git merge
git merge devv 将devv分支合并到当前分支下
- 首先位于master分支下
- 然后将devv分支合并到master中
git merge 冲突
git log
git log
列出历史提交信息
commit d5e9fc2c811e0ca2b2d28506ef7dc14171a207d9 (HEAD -> master) Merge: c68142b 7774248 Author: runoob <test@runoob.com> Date: Fri May 3 15:55:58 2019 +0800 Merge branch 'change_site' commit c68142b562c260c3071754623b08e2657b4c6d5b Author: runoob <test@runoob.com> Date: Fri May 3 15:52:12 2019 +0800 修改代码 commit 777424832e714cf65d3be79b50a4717aea51ab69 (change_site) Author: runoob <test@runoob.com> Date: Fri May 3 15:49:26 2019 +0800 changed the runoob.php commit c1501a244676ff55e7cccac1ecac0e18cbf6cb00 Author: runoob <test@runoob.com> Date: Fri May 3 15:35:32 2019 +0800
git log --oneline
查看历史记录的简洁的版本
d5e9fc2 (HEAD -> master) Merge branch 'change_site' c68142b 修改代码 7774248 (change_site) changed the runoob.php c1501a2 removed test.txt、add runoob.php 3e92c19 add test.txt 3b58100 第一次版本提交
git log --graph
查看历史中什么时候出现了分支、合并
* commit db9a961b1ca3be821b8cfa78d8efdb2ac872151c (HEAD -> master) | Merge: ae5a679 cd0b4d8 | | Author: 未月廿三 <zhangh0725@163.com> | | Date: Wed Nov 6 17:52:53 2019 +0800 | | | | resovle conflict in z.txt | | | * commit cd0b4d846cad5c2f4fc165924bc149c41430c69e (deve) | | Author: 未月廿三 <zhangh0725@163.com> | | Date: Wed Nov 6 17:50:42 2019 +0800 | | | | edit z.txt in deve | | * | commit ae5a679ba34e4032624e317c6cccc2ea499f8b22 |/ Author: 未月廿三 <zhangh0725@163.com> | Date: Wed Nov 6 17:49:35 2019 +0800 | | edit z.txt | * commit 30946d0fa354bd3b083615f81a1de5f582fccfa0 | Author: 未月廿三 <zhangh0725@163.com> | Date: Wed Nov 6 17:44:10 2019 +0800 | | add zzz | * commit 624f490542f1e2391a9486415f5d80fc0dc97c59 | Author: 未月廿三 <zhangh0725@163.com> | Date: Wed Nov 6 17:24:42 2019 +0800 | | 增加a.txt | * commit 17de157c7dd6e72268a99aabdf2deb73237c4e68 | Author: 未月廿三 <zhangh0725@163.com> | Date: Wed Nov 6 17:20:30 2019 +0800 | | 修改z.txt | * commit 2fb409050b63e96135bd2c7a83068bb891753824 Author: 未月廿三 <zhangh0725@163.com> Date: Tue Nov 5 16:42:17 2019 +0800 first commit by eternity
git log --reverse --oneline
--reverse 参数来逆向显示所有日志,即变为正序显示
2fb4090 first commit by eternity 17de157 修改z.txt 624f490 增加a.txt 30946d0 add zzz ae5a679 edit z.txt cd0b4d8 (deve) edit z.txt in deve db9a961 (HEAD -> master) resovle conflict in z.txt
git log --author=xxx --oneline -5
查找指定用户的提交日志可以使用命令:git log --author
git log --author=未月廿三 --oneline -5 只显示最近的5条,不加-5则全部显示 db9a961 (HEAD -> master) resovle conflict in z.txt cd0b4d8 (deve) edit z.txt in deve ae5a679 edit z.txt 30946d0 add zzz 624f490 增加a.txt
git log --oneline --before={xxx} --after={xxx}
要指定日期,可以执行几个选项:--since 和 --before,但是你也可以用 --until 和 --after,--no-merges 选项以隐藏合并提交
$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges 5469e2d Git 1.7.1-rc2 d43427d Documentation/remote-helpers: Fix typos and improve language 272a36b Fixup: Second argument may be any arbitrary string b6c8d2d Documentation/remote-helpers: Add invocation section 5ce4f4e Documentation/urls: Rewrite to accomodate transport::address 00b84e9 Documentation/remote-helpers: Rewrite description 03aa87e Documentation: Describe other situations where -z affects git diff 77bc694 rebase-interactive: silence warning when no commits rewritten 636db2c t3301: add tests to use --format="%N"
git remote
git remote
查看当前配置有哪些远程仓库
$ git remote origin
git remote -v
可以看到每个别名的实际链接地址
$ git remote -v origin git@github.com:tianqixin/runoob-git-test.git (fetch) origin git@github.com:tianqixin/runoob-git-test.git (push)
git remote add origin ***
链接并添加远程仓库远程仓库
# 首次链接并添加远程仓库 git remote add origin git@github.com:tianqixin/runoob-git-test.git
git fetch
git fetch origin
执行 git fetch [alias] 告诉 Git 去获取它有你没有的数据
$ git fetch origin remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:tianqixin/runoob-git-test 0205aab..febd8ed master -> origin/master
git merge
git merge origin/master
git merge [alias]/[branch] 以将服务器上的任何更新(假设有人这时候推送到服务器了)合并到你的当前分支
$ git merge origin/master Updating 0205aab..febd8ed Fast-forward README.md | 1 + 1 file changed, 1 insertion(+)
git push
git push [alias] [branch]
将你的 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支
$ touch runoob-test.txt # 添加文件 $ git add runoob-test.txt $ git commit -m "添加到远程" master 69e702d] 添加到远程 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 runoob-test.txt $ git push origin master # 推送到 Github
git remote rm
git remote rm [别名]
删除远程仓库(将本地版本库与远程仓库断开)
$ git remote -v origin git@github.com:tianqixin/runoob-git-test.git (fetch) origin git@github.com:tianqixin/runoob-git-test.git (push) # 添加仓库 origin2 $ git remote add origin2 git@github.com:tianqixin/runoob-git-test.git $ git remote -v origin git@github.com:tianqixin/runoob-git-test.git (fetch) origin git@github.com:tianqixin/runoob-git-test.git (push) origin2 git@github.com:tianqixin/runoob-git-test.git (fetch) origin2 git@github.com:tianqixin/runoob-git-test.git (push) # 删除仓库 origin2 $ git remote rm origin2 $ git remote -v origin git@github.com:tianqixin/runoob-git-test.git (fetch) origin git@github.com:tianqixin/runoob-git-test.git (push)
远程推送与下载
远程的分支与本地的分支名称要一样
# 将本地当前deve分支的内容推送到远程仓库deve分支,但是远程有新内容,需要先pull或者fetch/merge TheEternityZhang-MacBook:git-test zhtony$ git push origin deve To https://gitee.com/eternityz/git-test.git ! [rejected] deve -> deve (non-fast-forward) error: 推送一些引用到 'https://gitee.com/eternityz/git-test.git' 失败 提示:更新被拒绝,因为您当前分支的最新提交落后于其对应的远程分支。 提示:再次推送前,先与远程变更合并(如 'git pull ...')。详见 提示:'git push --help' 中的 'Note about fast-forwards' 小节。 # 查看本地的文件 TheEternityZhang-MacBook:git-test zhtony$ ls a.txt deve.txt test.txt z.txt zzz # 从远程deve分支拉取最新信息 TheEternityZhang-MacBook:git-test zhtony$ git fetch origin deve 来自 https://gitee.com/eternityz/git-test * branch deve -> FETCH_HEAD * [新分支] deve -> origin/deve # 查看没有合并之前的文件列表 TheEternityZhang-MacBook:git-test zhtony$ ls a.txt deve.txt test.txt z.txt zzz # 将远程的文件合并到本地,此命令错误,应该为origin/deve TheEternityZhang-MacBook:git-test zhtony$ git merge origin deve merge:origin - 不能合并 # 将远程的文件合并到本地 TheEternityZhang-MacBook:git-test zhtony$ git merge origin/deve Merge made by the 'recursive' strategy. README.md | 40 ++++++++++++++++++++++++++++++++++++++++ z.txt | 2 ++ 2 files changed, 42 insertions(+) create mode 100644 README.md # 查看分支,当前处于deve分支 TheEternityZhang-MacBook:git-test zhtony$ git branch * deve master # 查看文件列表 TheEternityZhang-MacBook:git-test zhtony$ ls README.md a.txt deve.txt test.txt z.txt zzz # 将本地当前deve分支的内容推送到远程仓库deve分支,推送成功 TheEternityZhang-MacBook:git-test zhtony$ git push origin deve 枚举对象: 6, 完成. 对象计数中: 100% (6/6), 完成. 使用 4 个线程进行压缩 压缩对象中: 100% (4/4), 完成. 写入对象中: 100% (4/4), 528 bytes | 528.00 KiB/s, 完成. 总共 4 (差异 2),复用 0 (差异 0) remote: Powered by GITEE.COM [GNK-3.8] To https://gitee.com/eternityz/git-test.git 5b6cce8..03cca4d deve -> deve
- 执行
git fetch origin master
时,它的意思是从名为 origin 的远程上拉取名为 master 的分支到本地分支 origin/master 中。既然是拉取代码,当然需要同时指定远程名与分支名,所以分开写。- 执行
git merge origin/master
时,它的意思是合并名为 origin/master 的分支到当前所在分支。既然是分支的合并,当然就与远程名没有直接的关系,所以没有出现远程名。需要指定的是被合并的分支。- 执行
git push origin master
时,它的意思是推送本地的 master 分支到远程 origin,涉及到远程以及分支,当然也得分开写了。- 还可以一次性拉取多个分支的代码:
git fetch origin master stable oldstable
;- 也还可以一次性合并多个分支的代码:
git merge origin/master hotfix-2275 hotfix-2276 hotfix-2290
;