美文网首页Git使用GitGit
Git初学笔记 就是这么简单@廖雪峰的Git教程

Git初学笔记 就是这么简单@廖雪峰的Git教程

作者: RoseauHan | 来源:发表于2017-08-23 19:22 被阅读312次

//此笔记基于廖雪峰的Git教程
Version 1.0 @2017.8.23 @RoseauHan
请勿用于商业用途

Git是目前世界上最先进的分布式版本控制系统,这是它诞生的故事
了解更多请参考文末的References,感谢阅读:)

创建版本库

初始化一个Git仓库,使用git init命令。
添加文件到Git仓库,分两步:

  • 第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件;
  • 第二步,使用命令git commit,完成。

时光机穿梭

要随时掌握工作区的状态,使用git status命令。
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。

版本回退
  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
工作区和暂存区

我们把文件往Git版本库里添加的时候,是分两步执行的:

  • 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

  • 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

  • git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
管理修改

为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。
第一次修改 -> git add -> 第二次修改 -> git commit
你看,我们前面讲了,Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,

  • git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

那怎么提交第二次修改呢?你可以继续git addgit commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了:
第一次修改 -> git add -> 第二次修改 -> git add -> git commit.

撤销修改
  • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
  • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file
    ,就回到了场景1,第二步按场景1操作。
  • 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除文件
  • 命令行删除 git rm file
  • 确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit
  • 如果删错,git checkout (用法: git checkout -- file)其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
    (一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。)

远程仓库

  • 第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
    $ ssh-keygen -t rsa -C "youremail@example.com"
    你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。
    如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

  • 第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:
    然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容。完成。

添加远程库

要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

常见问题

  • 1.当你第一次使用Git的clone或者push命令连接GitHub时,会得到一个警告:
    The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
    RSA key fingerprint is xx.xx.xx.xx.xx.
    Are you sure you want to continue connecting (yes/no)?
    这是因为Git使用SSH连接,而SSH连接在第一次验证GitHub服务器的Key时,需要你确认GitHub的Key的指纹信息是否真的来自GitHub的服务器,输入yes回车即可。
    Git会输出一个警告,告诉你已经把GitHub的Key添加到本机的一个信任列表里了:
    Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
    这个警告只会出现一次,后面的操作就不会有任何警告了。
    参考Referring:Connecting-to-github-with-ssh

  • 2.如何解决 failed to push some refs for git?
    出现错误的主要原因是github中的README.md文件不在本地代码目录中,可以通过如下命令进行代码合并 [注:pull=fetch+merge]
    git pull --rebase origin master
    执行上面代码后可以看到本地代码库中多了README.md文件,
    此时再执行语句 git push -u origin master即可完成代码上传到github。
    参考Referring:如何解决 failed to push some refs for git

从远程库克隆
  • 要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。

  • Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快.

  • 你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

  • 使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。

分支管理

Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。

创建与合并分支
  • 查看分支:git branch

  • 创建分支:git branch <name>

  • 切换分支:git checkout <name>

  • 创建+切换分支:git checkout -b <name>

  • 合并某分支到当前分支:git merge <name>

  • 删除分支:git branch -d <name>

解决冲突
  • 当出现Your branch is ahead of 'origin/master' by 1 commit.这种无法自动合并的情况时,就必须首先解决冲突,解决之后,再提交,合并完成。
  • 可以先用cat命令查看冲突,用带参数的git log命令git log --graph --pretty=oneline --abbrev-commit也可看到分支的合并情况。
  • 退出git log的方法: 输入q
分支管理策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

团队合作的分支看起来就像这样
  • Git分支十分强大,在团队开发中应该充分应用。合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
Bug分支

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;当手头工作没有完成时,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

  • 先把工作现场git stash一下,然后git checkout name切换分支去修复bug,

  • 修复后回到原工作分支,git status发现工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看,工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:

      • 一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
      • 另一种方式是用git stash pop,恢复的同时把stash内容也删了再git stash pop,回到工作现场。再用git stash list查看,就看不到任何stash内容了。
  • 你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:$ git stash apply stash@{0}

小结

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

Feature分支

开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除

多人协作

多人协作的工作模式通常是这样:

  • 首先,可以试图用git push origin branch-name推送自己的修改;

  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull
    试图合并;

  • 如果合并有冲突,则解决冲突,并在本地提交;

  • 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

  • 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name

小结

  • 查看远程库信息,使用git remote -v

  • 本地新建的分支如果不推送到远程,对其他人就是不可见的;

  • 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;

  • 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;

  • 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name

  • 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

标签管理

  • Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。

  • tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。

创建标签
  • 命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id : git tag v0.9 6224937

  • 可以用git show <tagname>查看标签信息

  • 可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
    $ git tag -a v0.1 -m "version 0.1 released" 3628164

  • git tag -s <tagname> -m "blablabla..."可以用PGP签名标签;
    签名采用PGP签名,因此,必须首先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错:gpg: signing failed: secret key not available error: gpg failed to sign the data error: unable to sign the tag
    如果报错,请参考GnuPG帮助文档配置Key。

  • 命令git tag可以查看所有标签。

操作标签
  • 命令git push origin <tagname>可以推送一个本地标签;

  • 命令git push origin --tags可以推送全部未推送过的本地标签;

  • 命令git tag -d <tagname>可以删除一个本地标签;

  • 命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

使用GitHub

  • 在GitHub上,可以任意Fork开源仓库;

  • 自己拥有Fork后的仓库的读写权限;

  • 可以推送pull request给官方仓库来贡献代码

自定义git

$ git config --global color.ui true Git会适当地显示不同的颜色

忽略特殊文件

忽略文件的原则是:

  • 忽略操作系统自动生成的文件,比如缩略图等;
  • 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是-
  • 通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
  • 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

忽略某些文件时,需要编写.gitignore:
.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理

参考Referring:[https://github.com/github/gitignore](https://github.com/github/gitignore)

配置别名
  • 如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的,实现方法:
    $ git config --global alias.你的缩写 原名 eg:
    $ git config --global alias.co checkout
    $ git config --global alias.ci commit
    $ git config --global alias.br branch

  • --global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。

  • 配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。

  • 每个仓库的Git配置文件都放在.git/config文件中:
    别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
    而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中;
    (配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。)

搭建Git服务器

点击标题直接查看

References

Git - Wikipedia
git - 简明指南
GitHub Help
图解Git

About me

Simple || Practical || Interest
c’est un roseau pensant.
不喜欢标签化却又不得不通过标签介绍自己的一个人。
目前,可以通过email RoseauHan@gmail.com 联系我,也可以通过我的简书个人主页的其他方式联系到我,欢迎关注RoseauHan的instagram主页。

相关文章

网友评论

    本文标题:Git初学笔记 就是这么简单@廖雪峰的Git教程

    本文链接:https://www.haomeiwen.com/subject/xehldxtx.html