Daily Growing

Git 笔记

2018-03-24

Git是分布式版本控制系统,没有“中央服务器”,每个人的电脑上都是一个完整的版本库。通常有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改。

命令

创建版本库

  • 选择一个合适目录,通过git init命令把这个目录变成Git可以管理的仓库:$ git init

  • 把一个文件放到Git仓库

    • 把文件添加到仓库:$ git add readme.txt;
    • 把文件提交到仓库:git commit -m "wrote a readme file" #-m后面输入的是本次提交的说明

修改

  • git status命令提示文件是否被修改过,随时掌握工作区的状态。

  • git diff readme.txt查看具体修改了什么内容 //之后还想提交继续git add <file>git commit 两步

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

  • git log命令查看历史记录 //后加 --pretty=oneline 简化显示结果

回退

  • 回退版本:git reset --hard HEAD^ 注意其中^的数量会变动,如上上一个版本就是HEAD^^; 或者把HEAD^直接改为目标版本的commit id。

  • git reflog用来记录用户的每一次命令

  • 提交后,用git diff HEAD -- <filename>命令可以查看工作区和版本库里面最新版本的区别

撤销修改

  • git checkout -- file可以丢弃工作区的修改
    (让这个文件回到最近一次git commit或git add时的状态。)

  • git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区:

  • (已经提交到版本库但后续删除了的文件)
    删除版本库中的该文件:1. git rm <filename>;2. git commit -m "balabala"
    根据版本库恢复该文件:git checkout -- <filename> (git checkout其实是用版本库里的版本替换工作区的版本)

远程仓库

  • Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。

创建ssh key

  • 在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
    $ ssh-keygen -t rsa -C "youremail@example.com"
    一路回车,使用默认值即可
    之后把id_rsa.pub中的内容设置到GitHub账户设置中就行了

添加远程库

  1. 把创建好的SSH公钥放入Github账户设置中
  2. 在Github上新建一个repo
  3. 在本地想要推送的文件中:git remote add <origin> git@github.com:<username>/<repo's name>.git
  4. 关联后,使用命令git push -u <origin> master第一次推送master分支的所有内容;
  5. 之后git push <origin> master推送最新修改

参与开源项目

  • 访问它的项目GitHub主页,点“Fork”就在自己的账号下克隆了一个仓库,然后,从自己的账号下clone git clone git@github.com:<username>/<repo's name>.git 一定要从自己的账号下clone仓库,这样你才能推送修改。

  • 如果希望官方库能接受自己的修改,可以在GitHub上发起一个pull request。当然,对方是否接受pull request就不一定了

  • 已关联GitHub远程库的文件夹再关联码云

    1. 码云中添加ssh公钥
    2. 码云中创建项目
    3. 本地中先用git remote -v查看远程库信息
    4. 删除已有的GitHub远程库:git remote rm origin
    5. 在本地库上使用命令git remote add把它和码云的远程库连接:git remote add origin git@gitee.com:<username>/<repo's name>.git
    6. 通过git push命令就可以把本地库推送到Gitee上
  • 一个本地库能既关联GitHub,又关联码云。如果有多个远程库,需要用不同的名称来标识不同的远程库

    1. 先删除已关联的名为origin的远程库 git remote rm origin
    2. 先关联GitHub的远程库:git remote add github git@github.com:<username>/<repo's name>.git注意,远程库的名称叫github,不叫origin了
    3. 再关联码云的远程库:git remote add gitee git@gitee.com:/<repo’s name>.git
    4. 如果要推送到GitHub,使用命令:git push github master
  • git stash保存当前工作现场;git stash list查看刚才存储工作现场的具体位置;git stash pop恢复工作现场

分支

  • 创建dev分支,然后切换到分支:git checkout -b dev 包含了如下两个命令

    • 创建:git branch dev
    • 切换:git checkout dev
  • git branch命令查看当前分支,当前分支前面会标一个*号

  • 把dev分支的工作成果合并到master分支:先用checkout命令切换到master分支,再git merge dev合并指定分支到当前分支

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

  • git branch -D feature-vulcan 强行删除未合并的分支

  • 解决冲突:当两个分支各自分别有新的提交,这种情况下,Git无法执行“快速合并”,需要手动合并后提交。

  • 通常合并分支时Git会用Fast forward模式,删除分支后会丢掉分支信息。如果要强制禁用Fast forward模式,从分支历史上就可以看出分支信息,则使用命令(示例在master分支上合并自建分支dev的内容):git merge --no-ff -m "merge with no-ff" dev

  • git stash 把当前工作现场“储藏”起来,等以后恢复现场后继续工作。有两种恢复方式:

    • git stash apply恢复,stash内容并不删除,需要用git stash drop来删除;

    • 另一种方式是用git stash pop,恢复的同时把stash内容也删了:

  • git push origin <分支名字>把该分支上的所有本地提交推送到远程库

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

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

    1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
    2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull(抓取冲突)试图合并;
    3. 如果合并有冲突,则解决冲突,并在本地提交;没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
    4. 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream <branch-name> origin/<branch-name>

标签管理

Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针。创建和删除标签都是瞬间完成的。

  • 在Git中打标签

    1. 切换到需要打标签的分支上;
    2. git tag v1.0打标签
    3. git tag 查看标签
    4. 给特定的commit打标签:git tag <name> <commit-id>(commit-id可以用git log --pretty=oneline --abbrev-commit查看)
  • git show <tagname>查看标签信息 <tagname>如 v1.0

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

  • 操作标签

    1. git push origin <tagname>可以推送一个本地标签
    2. git push origin --tags可以推送全部未推送过的本地标签
    3. git tag -d <tagname>可以删除一个本地标签
    4. git push origin :refs/tags/<tagname>可以删除一个远程标签(注意若想删除的标签已推送远程,需先删除本地标签再删除远程标签)
  • git check-ignore -v <App>.<class>找出该类型文件关联了.gitignore哪个规则

补充

  • 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

  • (回退)
    场景1:想直接丢弃工作区的修改时:git checkout -- file
    场景2:改乱了工作区并添加到了暂存区时,想丢弃修改:第一步用命令git reset HEAD file,第二步见场景1。
    场景3:已经提交了不合适的修改到版本库时想要撤销:git reset --hard HEAD^

  • 创建SSH key

  • 忽略某些文件时,需要编写.gitignore;.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理;-f强制添加已忽略格式类型的文件:git add -f <App>.<class>