Git学习笔记(超详细⼊门总结教程)
Git学习笔记(超详细⼊门总结教程)
本⽂是根据廖雪峰的教程整理⽽成的个⼈笔记,仅供学习参考之⽤,在此万分感谢!
⽂章⽬录
1 版本库与⽂件操作
1.1 创建版本库
什么是版本库呢?版本库⼜名仓库,英⽂名repository,你可以简单理解成⼀个⽬录,这个⽬录⾥⾯的所有⽂件都可以被Git管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
⾸先在GitBash中cd到要创建仓库的位置(或者直接进⼊相应⽬录,点⿏标右键然后选择Git Bash Here),执⾏git init,仓库创建成功后会在仓库⽂件夹中⽣成 .git⽬录 ,这个⽬录是Git来跟踪管理版本库的 ,千万不要⼿贱修改。我们创建Git版本库时,Git会⾃动为我们创建唯⼀⼀个master分⽀ .
1.2 添加⽂件到Git仓库
  1. git add <fileName>,将⽂件放进暂存区(stage) ,此命令可反复多次使⽤,也可同时添加多个⽂件;
  2. 使⽤命令git commit -m <message>,添加到版本库 ,即把暂存区的所有内容提交到当前分⽀ ,其中<message>是本次提交的描述;
1.2.1 查看仓库状态
git status命令可以随时掌握⼯作区/仓库当前的状态 (显⽰有变更的⽂件),此命令的⼏种结果如下:
  1. Changes not staged for commit:⽂件更改了,但是还未进⼊暂存区 ,需要add;
  2. Changes to be committed:⽂件已进⼊暂存区,但还未提交到版本库,需要commit;
  3. Untracked files:表⽰该⽂件还从来没有被添加进版本库,这是新添加的⽂件;
1.2.2 查看修改内容
  如果git status告诉你有⽂件被修改过,⽤git diff可以查看修改内容,语法为:git diff <fileName>,add⽂件之前最好看⼀下。(⽐较⽂件的不同,即暂存区和⼯作区的差异。)
1.2.3 提交修改
  提交修改和提交新⽂件是⼀样的两步 :add和commit。可以简单理解为,需要提交的⽂件修改通通放到暂存区,然后,⼀次性提交暂存区的所有修改。
1.3 版本回退
  每当你觉得⽂件修改到⼀定程度的时候,就可以“保存⼀个快照”,这个快照在Git中被称为commit。⼀旦你把⽂件改乱了,或者误删了⽂件,还可以从最近的⼀个commit恢复,然后继续⼯作,⽽不是把⼏个⽉的⼯作成果全部丢失。
  1. git log 可以查看提交历史记录(即查看版本库的状态 ),显⽰从最近到最远的提交⽇志;git log --pretty=oneline 使每个⽇志单独成⾏(简化版输出)。
  2. git中,⽤HEAD表⽰当前版本(commit id 版本号)。
  3. 回退到上⼀个版本:git reset --hard HEAD^,HEAD^表⽰回退1个版本,HEAD^^表⽰回退2个版本,HEAD~100表⽰回退100个版本。HEAD其实是个指向当前版本的指针。
  4. 返回过去/未来的版本:git reset --hard 新版本的commit id。其中“新版本的commit id”可以只写id号的前⼏位,Git会⾃动去。
  5. git reflog查看历史每⼀次命令,可以查看每⼀次提交时的commit id。
1.4 ⼯作区和暂存区
⼯作区:就是当前的⼯作⽬录。
版本库:⼯作区⾥⾯隐藏的.git⽬录(这个不算⼯作区)就是Git的版本库。
  Git的版本库中存了很多东西,其中最重要的就是称为stage(或者称为index)的暂存区,还有Git为我们⾃动创建的第⼀个分
⽀master,以及指向master的⼀个指针叫HEAD。
  git add + git commit:可以理解为把⽂件修改添加到暂存区,然后⼀次性提交暂存区的所有内容到当前分⽀。 如图:
  注:Git跟踪并管理的是修改,⽽⾮⽂件。 git commit只负责把暂存区的修改提交。每次修改,如果不git add到暂存区,那就不会加⼊到commit中。
  提交后,⽤git diff HEAD -- 命令可以查看⼯作区和版本库⾥⾯最新版本的区别 。
补充:
git diff #是⼯作区(work dict)和暂存区(stage)的⽐较,⽐较的是⼯作区⽂件与暂存区⽂件的区别(上次git add后的内容)的区别。
git diff --cached #是暂存区(stage)和分⽀(master)的⽐较,⽐较的是暂存区的⽂件与仓库分⽀⾥(上次git commit后的内容)的区别 。
1.5 撤销修改
  场景1. 当你改乱了⼯作区某个⽂件的内容,想直接丢弃⼯作区的修改时,⽤命令git checkout -- <file>,这⾥有两种情况:
1. 若⽂件⾃修改后还没有被放到暂存区,现在,撤销修改就回到和版本库⼀模⼀样的状态;
2. 若⽂件已经添加到暂存区后,⼜作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个⽂件回到最近⼀次git commit或git add时的状态。
  场景2. 当你不但改乱了⼯作区某个⽂件的内容,还添加到了暂存区时,想丢弃修改,分两步,第⼀步⽤命令git reset HEAD <file>,把暂存区的修改撤销掉(unstage),重新放回⼯作区 ,回到了场景1。第⼆步按场景1操作,丢弃⼯作区的修改即可。
注:git reset命令既可以回退版本,也可以把暂存区的修改回退到⼯作区。当我们⽤HEAD时,表⽰最新的版本。
  场景3. 已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退那⼀节,可以回退到上⼀个版本,不过前提是你还没有把⾃⼰的本地版本库推送到远程,否则就JJ了。
补充:
Unix/Linux 命令中,- 后⼀般跟短命令选项(通常是单字母,如-m),-- 后⼀般跟长命令选项。如果只有⼀个单独的--,后⾯不紧跟任何选项,则表⽰命令选项结束,后续的都作为命令的参数⽽不是选项。例如:
git checkout -- filename(git checkout其实是⽤版本库⾥的版本替换⼯作区的版本,⽆论⼯作区是修改还是删除,都可以“⼀键还原”。)filename作为git checkout 的参数,⽽不是选项。
1.6 删除⽂件
  ⼿动删除或者⽤命令rm <fileName>删除⽂件后,执⾏git add/rm <fileName>和git commit-m <message>就可以了。
  另⼀种情况是删错了,因为版本库⾥还有呢,所以可以很轻松地把误删的⽂件恢复到最新版本git checkout -- file 。
git checkout其实是⽤版本库⾥的版本替换⼯作区的版本,⽆论⼯作区是修改还是删除,都可以“⼀键还原”。
2 远程仓库
  Git是分布式版本控制系统,同⼀个Git仓库,可以分布到不同的机器上。 每个⼈都从“服务器”仓库上克隆⼀份到⾃⼰的电脑上,并且各⾃把各⾃的提交推送到服务器仓库⾥,也从服务器仓库中拉取别⼈的提交。
  本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要⼀点设置:
1. 创建SSH Key。
ssh-keygen -t rsa -C "youremail@example"# ⼀路回车即可,⽆需设置密码
此时可以在⽤户主⽬录⾥到.ssh⽬录,⾥⾯有id_rsa和id_rsa.pub两个⽂件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放⼼地告诉任何⼈。
2. 打开GitHub,在个⼈主页到setting,到SSH and GPG keys,然后,点“New SSH Key”,填上任意Title,在Key⽂本框⾥粘贴
id_rsa.pub⽂件的内容,完后确定添即可。 注:GitHub允许你添加多个Key。
2.1 添加远程库
  让本地和远程仓库同步。在GitHub上新建仓库,此时既可以从这个仓库克隆出新的仓库,也可以把⼀个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
1. 在本地的learnGit仓库下运⾏如下命令(先有本地库时,将本地库和远程库关联),此时远程库的名字就是origin。
git remote add origin git@github:ft-sunshine/learngit.git      # 需改
2. 把本地库的所有内容推送到远程库上 ,实际上是把当前分⽀master推送到远程。 由于远程库是空的,我们第⼀次推送master分⽀
时,加上了-u参数,Git不但会把本地的master分⽀内容推送到远程新的master分⽀,还会把本地的master分⽀和远程的master分⽀关联起来,在以后的推送或者拉取时就可以简化命令。 (去掉-u)
git push -u origin master    # 第⼀次推送
git push origin master      # 本地提交后,如有必要,可推送本地的最新修改。
2.2 从远程库克隆
git clone git@github:ft-sunhine/gitskills.git
如果有多个⼈协作开发,那么每个⼈各⾃从远程库克隆⼀份就可以了。
3 分⽀管理
  如果你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀上,这样,既安全,⼜不影响别⼈⼯作。
3.1 分⽀与管理
git常用指令
每次提交,Git都把它们串成⼀条时间线,这条时间线就是⼀个分⽀。
严格来说HEAD并不是指向提交,⽽是指向master(HEAD指向当前分⽀),master(当前分⽀)才是指向提交的(指向当前分⽀的提交点)。所以,HEAD指向的就是当前分⽀,其可以确定当前的分⽀。 这部分还是推荐看下官⽹的图,更易理解。
Git⿎励⼤量使⽤分⽀:
  1. 查看分⽀:git branch
  2. 创建分⽀(相当于增加了⼀个dev指针):git branch <name> ,切换分⽀:git checkout <name>
  3. 创建+切换分⽀:git checkout -b <name>
  4. 合并指定分⽀到当前分⽀:git merge <name>
  5. 删除分⽀:git branch -d <name>
例⼦如下:
创建分⽀dev:git checkout -b dev
在dev分⽀上进⾏⼀通操作
合并分⽀ ,先git checkout master切换到主分⽀,然后执⾏git merge dev进⾏合并。然后可以再执⾏git branch -d dev删除分⽀
3.2 解决冲突
  合并分⽀时就可能出现代码冲突,任何合并冲突都必须⼈去解决。⼈⽣不如意之事⼗之⼋九,合并分⽀往往也不是⼀帆风顺的。
  其实冲突的本质是:不同的分⽀修改了代码相同的部分,从⽽导致合并分⽀时出现冲突(虽然冲突,但还是会合并,会⾃动标注出冲突的地⽅)。所以解决冲突就需要我们把Git合并失败的⽂件进⾏⼿动修复,改为我们想要的内容再提交(add + commit)即可。
  可以⽤带参数的git log查看分⽀的合并情况(分⽀合并图): git log --graph --pretty=oneline --abbrev-commit
3.3 分⽀管理策略
  合并分⽀时,默认采取的为Fast farword模式,这种合并看不到合并历史,删除分⽀会丢掉分⽀信息。
  禁⽤Fast farword模式时,合并分⽀时会产⽣⼀个新的commit,这样,从分⽀历史上就可以看出分⽀信息。 ⽤git merge --no-ff -m "merge with no-ff" dev 命令合并,其中,--no-ff参数,表⽰禁⽤Fast forward模式。 因为本次合并要创建⼀个新的commit,所以加上-m参数,把commit描述写进去。
$ git log --graph --pretty=oneline --abbrev-commit  // 查看分⽀历史
*  e1e9c68 (HEAD -> master) merge with no-ff
|\
| * f52c633 (dev) add merge    //可以看到⽤--no-ff参数,合并分⽀时会新创建⼀次提交
|/
*  cf810e4 conflict fixed
...
  可以看到,不使⽤Fast forward模式,merge后就像这样 :
分⽀策略(分⽀管理原则)图如下:
3.4 Bug分⽀
  修复bug,每个bug都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。
假设场景是这样的:A为正在开发的软件

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。