JanZou analyst, programmer

Git简明使用


一直使用Git来进行版本控制,这里总结一下Git使用的基本命令。

若需详细学习,可参考《Pro Git》《Git权威指南》等书籍。

配置

git config [option] 查看已有配置信息: git config --list 编辑配置文件: git config -e

~/.gitconfig文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 –global 选项,读写的就是这个文件。 git push.default设置:push.default可用值(nothing, current, upstream, simple, matching)

初始化及添加

  • 创建版本库 当前目录下多了一个.git的目录,用于跟踪管理版本库。

      $ mkdir folder
      $ cd folder
      $ git init
      $ git init --bare  # 不含项目源文件拷贝
    
  • 把文件添加到版本库 只跟踪文本文件的改动;文件一定要放在版本库的目录下。 把一个文件放到Git仓库只需要两步。第一步,用命令git add告诉Git,把文件添加到仓库;第二步,用命令git commit告诉Git,把文件提交到仓库。

      $ git add readme.txt
      $ git commit -m "wrote a readme file"
    
      $ git commit -a -m "xxxx"   #自动把所有已经跟踪过的文件暂存起来一并提交
    
  • 文件改名

      $ git mv old_file new_file
    
  • 查看仓库当前状况(被修改的文件)

      $ git status
    
  • 查看具体修改内容 查看工作目录中当前文件和暂存区域快照之间的差异:

      $ git diff readme.txt
    

    查看已经暂存起来的文件和上次提交时的快照之间的差异:

      $ git diff --cached
      $ git diff --staged
    
      git diff HEAD //与上次 commit 之间的差别 (爸爸)
      git diff HEAD^ //与上上次(爷爷)
      git diff HEAD^^ //与上上上次
      git diff HEAD~5 //与前面第5次commit
      git diff HEAD^..HEAD //中间是两个点比较(爸爸)和(爷爷)的差别
      git diff f5fdjsalfjdskaf..4fdklsajfdksaf //比较两个不同hash值记录之间的不同
      git diff master bird //比较branch之间的不同
    

版本回退

  • 查看提交历史记录(以便确定要回退到哪个版本)

      $ git log
          -p 展开显示每次提交的内容差异
          -n 显示最近的n次提交更新
          -stat 显示每次更新的文件修改统计信息
          --since, --after 仅显示指定时间之后的提交
          --until, --before 仅显示指定时间之前的提交
          --author 仅显示指定作者相关的提交
    
  • 查看命令历史(找到commit id, 以便确定要回到未来的哪个版本)

      $ git reflog
    
  • HEAD指向的版本是当前版本,可根据commit id穿梭于各个版本之中 (上个版本是HEAD^,上上个版本是HEAD ^,往上100个版本是HEAD~100)

      $ git reset --hard HEAD^
      或
      $ git reset --hard 811f666 ("commit id")
    

工作区和版本库

  • 工作区(Working Directory):电脑中能看到的目录
  • 版本库(Repository):工作区中的一个隐藏目录“.git” Git版本库中存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git自动创建的第一个分支master,以及指向master的一个指针叫HEAD。 前面讲把文件添加到Git版本库,是分两步执行的:
    • git add:把文件修改添加到暂存区
    • git commit:把暂存区的所有内容提交到当前分支版本库

git

对于任何一个文件,在Git中都只有三种状态:已提交(committed)、已修改(modified)、已暂存(staged)。 文件流转的三个工作区域:工作目录、暂存区域、Git本地数据目录。

管理修改

Git跟踪并管理的是修改,而非文件。每次修改若不添加到暂存区中,则不会被提交到分支上。

撤销修改

  • 改乱了工作区某文件的内容,直接丢弃并回到上次提交点 把版本库的内容复制到工作目录中,丢失从上一次提交后到现在的所有修改。

      $ git checkout -- readme.txt
    
  • 改乱了工作区某文件的内容,并添加到了暂存区 把暂存区的修改撤销掉,重新放回工作区。 git reset命令既可以回退版本,也可以把工作区的某些文件替换为版本库中的文件。当使用HEAD时,表示最新的版本。

      $ git reset HEAD readme.txt    # 暂存区干净,工作区有修改
      $ git checkout -- readme.txt    # 丢弃工作区的修改
    
  • 提交了不合适的修改到版本库,但没有推送到远程库。要撤销本次提交,参考版本回退。

删除文件

  • 从版本库删除文件

      $ git rm test.txt
      $ git commit -m "remove test.txt"
    
  • 移除跟踪,但不删除文件

      $ git rm --cached test.txt
    
  • 把工作区中误删的文件恢复到最新版本

      $ git checkout -- test.txt
    

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“⼀键还原”。

如果⼀个文件已经被提交到版本库,那么永远不用担心误删,但只能恢复文件到最新版本,会丢失最近一次提交后你修改的内容。

分支管理

  • 创建分支

      $ git branch name
    
  • 切换分支

      $ git checkout name
    
  • 创建+切换分支

      $ git checkout -b name
    
  • 查看当前分支 会列出所有分支,当前分支前面会标一个*号。

      $ git branch
        -a  列出所有分支
        -r  列出远程分支
    
  • 合并指定分支到当前分支

      $ git merge name
    
  • 衍合

      $ git rebase -i HEAD~n
    
  • 删除分支

      $ git branch -d name
    
  • 解决冲突 当Git无法自动合并分支时,必须首先解决冲突。解决冲突后,再提交,合并完成。用git log --graph命令可以看到分支合并图。

  • 合并分支时,通常使用“Fast forward”模式,但在该模式下,删除分支后,会丢掉分支信息。如果要强制禁用“Fast forward”模式,Git会在合并分支时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

      $ git merge --no-ff -m "merge with no-ff" dev
    
  • Bug分支 若手头的工作没有完成,有需要去修复bug。先将当前工作现场“储藏”起来,等修复完bug后在恢复现场继续工作。

      $ git stash
    

    查看“储藏”的工作现场:

      $ git stash list
    

    恢复工作现场有两种办法:一是用git stash apply恢复,但恢复后,stash内容并不删除,需要用git stash drop删除;另一种方法是用git stash pop,恢复的同时把stash内容删除。

  • 强制删除分支 若要丢弃一个没有被合并过的分支,可强制删除。

      $ git branch -D name
    

远程仓库(GitHub)

  • 关联一个远程库GitHub 远程库的名字就是origin,这是Git默认的叫法,也可以改成别的。

      $ git remote add [name] [url]
      $ git remote add origin git@github.com/username/projectname.git
    
  • 首次推送本地仓库内容到远程库 把本地库的内容推送到远程,使用git push命令,实际上是把当前分支master推送到远程。

      $ git push -u origin master
    
  • 以后,推送最新修改

      $ git push [远程仓库] [本地分支]
      $ git push origin master
    
      $ git push 远程仓库 本地分支:远程分支
    
  • 从远程库克隆

      $ git clone https://github.com/username/projectname.git
    
  • 查看远程库信息

      $ git remote -v
    
  • 抓取分支

      $ git pull [远程仓库] [远程分支xx/xxx]:[本地分支]
      $ git pull     # 抓取数据并合并
      $ git fetch [远程仓库] [远程分支]   # 不自动合并
    
      $ git pull --rebase [远程仓库] [远程分支]
    

git fetch 所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取。比如origin主机的master,就要用origin/master读取.

  • 建立本地分支和远程分支的关联

      $ git branch --set-upstream branch-name origin/branch-name
    
  • 删除远程分支

      $ git push [远程仓库] :[远程分支]
    
  • 远程仓库重命名和删除

      $ git remote rename oldname newname
      $ git remote rm name
    

标签管理

发布一个版本时,通常先在版本库中打一个标签,这样就唯一确定了打标签时刻的版本。标签也是版本库的一个快照。

  • 新建标签 参数:-a指定标签名;-m指定说明文字;-s用私钥签名一个标签,签名采用PGP;-d用来删除标签

      $ git tag name
      或
      $ git tag name commit id
    
  • 查看所有标签

      $ git tag
    
  • 查看标签信息

      $ git show tag name
    
  • 推送一个本地标签

      $ git push origin tag name
    
  • 推送全部本地标签

      $ git push origin --tags
    
  • 删除远程标签

      $ git tag -d tag name    # 本地删除
      $ git push origin :refs/tags/tagname    # 远程删除
    

忽略特殊文件

有时候必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件等。可以在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。

GitHub上为我们提供了各种配置文件,无需从头开始写.gitignore文件。

需要忽略的文件包括:

  1. 操作系统自动生成的文件
  2. 编译生成的中间文件、可执行文件等
  3. 带有敏感信息的配置文件

其他

  $ git blame filename  查看每行代码的修改者等信息