0 认识⼯作区、暂存区、版本库
⼯作区:是在电脑上你要写代码或⽂件的⽬录。
暂存区:英⽂叫stage或index。⼀般存放在.git ⽬录下的index⽂件(.git/index)中,我们
把暂存区有时也叫作索引(index)。
版本库:⼜名仓库,英⽂名 repository 。⼯作区有⼀个隐藏⽬录.git ,它不算⼯作区,⽽
是Git的版本库。这个版本库⾥⾯的所有⽂件都可以被Git管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
1. Git的基本操作
1.1 配置git
当安装Git后⾸先要做的事情是设置你的⽤⼾名称和e-mail地址,这是⾮常重要的。配置命令为:
git config [--global] user.name "Your Name"
git config [--global] user.email "email@example.com"
/*
其中 --global 是⼀个可选项。如果使⽤了该选项,表⽰这台机器上所有的Git仓库都会使⽤这个
配置。如果你希望在不同仓库中使⽤不同的 name 或 e-mail ,可以不要 --global 选项,但要
注意的是,执⾏命令时必须要在仓库⾥。
*/
查看配置:
git config -l
删除对应的配置:
git config [--global] --unset user.name
git config [--global] --unset user.email
1.2 初始化一个git仓库
创建⼀个Git本地仓库对应的命令为git init ,注意命令要在⽂件⽬录下执⾏
git init
执行命令之后当前目录下会创建一个隐藏文件git在 .git的目录结构中,需要注意的有:
• index:暂存区, git add 后会更新该内容。
• HEAD:默认指向master分⽀的⼀个指针。
• refs/heads/master:⽂件⾥保存当前 master 分⽀的最新 commit id 。
• objects:包含了创建的各种版本库对象及内容,可以简单理解为放了git维护的所有修改。
1.3 git常用命令
• 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] ...
• 添加指定⽬录到暂存区,包括⼦⽬录: git add [dir]
• 添加当前⽬录下的所有⽂件改动到暂存区: git add .
再使⽤ git commit 命令将暂存区内容添加到本地仓库中:
• 提交暂存区全部内容到本地仓库中:git commit -m "message"
• 提交暂存区的指定⽂件到仓库区: git commit [file1] [file2] ... -m "message"
注意 git commit 后⾯的 -m 选项,要跟上描述本次提交的message,由⽤⼾⾃⼰完成,这部分内容绝对不能省略,并要好好描述,是⽤来记录你的提交细节,是给我们⼈看的
我们可以使⽤ git log 命令,来查看下历史提交记录
git reflog 该命令⽤来记录本地的每⼀次命令
查看仓库状态 git status
显⽰暂存区和⼯作区⽂件的差异 git diff [file]
版本库和⼯作区⽂件的区别 git diff HEAD -- [file]
1.3.1版本回退
执⾏ git reset 命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下“回退”本质是要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:
git reset [--soft | --mixed | --hard] [HEAD]
--mixed 为默认选项,使⽤时可以不⽤带该参数。该参数将暂存区的内容退回为指定提交版本内容,⼯作区⽂件保持不变。
• --soft 参数对于⼯作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
• --hard 参数将暂存区与⼯作区都退回到指定版本。切记⼯作区有未提交的代码时不要⽤这个命令,因为⼯作区会回滚,你没有提交的代码就再也找不回了,所以使⽤该参数前⼀定要慎重。
• HEAD 说明:
◦ 可直接写成commit id,表⽰指定退回的版本
◦ HEAD表⽰当前版本
◦ HEAD^上⼀个版本
◦ HEAD^^上上⼀个版本
◦ 以此类推...
• 可以使⽤〜数字表⽰:
◦ HEAD~0表⽰当前版本
◦ HEAD~1上⼀个版本
◦ HEAD^2上上⼀个版本
◦ 以此类推...
1.3.2 撤销修改
如果我们在我们的⼯作区写了很⻓时间代码,越写越写不下去,觉得⾃⼰写的实在是垃圾,想恢复到上⼀个版本。
情况⼀:对于⼯作区的代码,还没有 add:
我们可以使⽤ git checkout -- [file] 命令让⼯作区的
⽂件回到最近⼀次add 或 commit 时的状态。要注意 git checkout -- [file] 命令中的
-- 很重要,切记不要省略,⼀旦省略,该命令就变为其他意思了
情况⼆:已经 add ,但没有 commit
让我们来回忆⼀下学过的 git reset 回退命令,该命令如果使⽤ --mixed 参数,可以将暂存区的内容退回为指定的版本内容,但⼯作区⽂件保持不变。那我们就可以回退下暂存区的内容了!!!
还记得如何丢弃⼯作区的修改吗?
git checkout -- [file]
情况三:已经 add ,并且也 commit 了
不要担⼼,我们可以 git reset --hard HEAD^ 回退到上⼀个版本!不过,这是有条件的,就是
你还没有把⾃⼰的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后⾯会讲到远程版本库,⼀旦你推送到远程版本库,你就真的惨了……
1.4 分支管理
1.4.1 创建分支
git branch #查看当前本地所有分⽀
#* master
git branch dev #新建分⽀dev
1.4.2 切换分支
git checkout dev
当我们切换到dev分支开发后,即使在dev上提交了代码,如果切换回master分支是看不到在dev上的修改的。 如果要在master分支上看到dev上修改的代码,下面就要引入分支合并技术了。
1.4.3 分支合并
为了在master主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分⽀,⽰例如下
git checkout master # 切换到 master 上进⾏合并
#Switched to branch 'master'
git merge dev # 合并 dev 分⽀
Fast-forward代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。当然,也不是每次合并都能Fast-forward,我们后⾯会讲其他⽅式的合并。
1.4.4 删除分支
合并完成后,dev分⽀对于我们来说就没⽤了,那么dev分⽀就可以被删除掉,注意如果当前正处于某分⽀下,就不能删除当前分⽀。
git branch -d dev
git branch -D dev #删除没有合并的分支 慎重使用
1.4.5 合并冲突
如果我在master分支上和dev分支上都提交过代码,在合并代码时就可能发生合并冲突。
此时我们必须要⼿动调整冲突代码,并需要再次提交修正后的结果!!(再次提交很重要,切勿忘记)。
1.4.6 分⽀管理策略
Git⽀持我们强制禁⽤ Fast forward 模式,那么就会在merge时⽣成⼀个新的 commit ,这样,从分⽀历史上就可以看出分⽀信息。
git merge --no-ff -m "merge with no-ff" dev
#因为相当于新的commit所以要 -m 把描述写进去
所以在合并分⽀时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾经做过合并,⽽ fast forward 合并就看不出来曾经做过合并。
在实际开发中,我们应该按照⼏个基本原则进⾏分⽀管理:
⾸先,master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活;
那在哪⼲活呢?⼲活都在dev分⽀上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布时,再把dev分⽀合并到master上,在master分⽀发布1.0版本;
你和你的⼩伙伴们每个⼈都在dev分⽀上⼲活,每个⼈都有⾃⼰的分⽀,时不时地往dev分⽀上合并就可以了。
所以,团队合作的分⽀看起来就像这样:
1.6.7 bug分支
假如我们现在正在 dev2 分⽀上进⾏开发,开发到⼀半,突然发现 master 分⽀上⾯有bug,需要解决。在Git中,每个bug都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。可现在 dev2 的代码在⼯作区中开发了⼀半,还⽆法提交,怎么办?
Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时间恢复出来。
git stash #隐藏工作区
git stash pop #恢复工作区
由于我们要基于master分⽀修复bug,所以需要切回 master 分⽀,再新建临时分⽀来修复bug。修复完成后,切换到 master 分⽀,并完成合并,最后删除 fix_bug 分⽀。
Master 分⽀⽬前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们在 dev2 中当然看不⻅修复 bug 的相关代码。我们的最终⽬的是要让 master 合并 dev2 分⽀的 。
2. 远程操作
2.1 克隆远程仓库
git clone
SSH 协议和 HTTPS协议是 Git 最常使⽤的两种数据传输协议。SSH协议使⽤了公钥加密和公钥登陆机制,体现了其实⽤性和安全性,使⽤此协议需要将我们的公钥放上服务器,由 Git服务器进⾏管理。使⽤ HTTPS ⽅式时,没有要求,可以直接克隆下来。
使⽤ SSH ⽅式克隆仓库,由于我们没有添加公钥到远端库中,服务器拒绝了我们的clone链接。
第⼀步:创建SSH Key。在⽤⼾主⽬录下,看看有没有.ssh⽬录,如果有,再看看这个⽬录下有没有id_rsa 和 id_rsa.pub 这两个⽂件,如果已经有了,可直接跳到下⼀步。如果没有,需要创建SSH Key:
ssh-keygen -t rsa -C "your email"
顺利的话,可以在⽤⼾主⽬录⾥找到 .ssh ⽬录,⾥⾯有 id_rsa 和 id_rsa.pub 两个⽂件,这两个就是SSH Key的秘钥对, id_rsa 是私钥,不能泄露出去, id_rsa.pub 是公钥,可以放⼼地告诉任何⼈。
第⼆步:添加⾃⼰的公钥到远端仓库。
2.2 远程推送
git push <远程主机名> <本地分⽀名>:<远程分⽀名> #将本地仓库的内容推送⾄远程仓库
# 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:
git push <远程主机名> <本地分⽀名>
# 从远程获取代码并合并本地的版本
git pull <远程主机名> <远程分⽀名>:<本地分⽀名>
# 如果远程分⽀是与当前分⽀合并,则冒号后⾯的部分可以省略。
git pull <远程主机名> <远程分⽀名>