你应该知道的 git 命令

381 阅读9分钟

梳理了一些 git 的入门命令,分享出来,欢迎指正学习。

简介

git 是十多年前 Linus 不爽现有的版本控制软件。相比于 cvs/svn 这些「中心化」的,以 diff 为基础存储更新的传统版本控制软件不同的是,git 认为每个文件一旦写入对象数据库中都是不可更改的(immutable),任何微小的修改,都会在数据库中形成一个新的对象。对象的 id 就是其 sha1 哈希。有了这个基础,文件对象(blob)可以被组织成树(更确切地说是默克尔树),一次 提交(commit)就是根据更改的文件的信息生成新的树的过程,新树和老树共享相同的子树,只有变化的部分才会分叉。在漫长的操作之后,对象数据库中有无数棵树,这些树构成了一个默克尔图(merkle DAG)。通过使用引用(ref),比如 HEAD, heads/master,tags/v0.1,git 可以很方便地追踪用户关心的每一棵树的确切状态。

原理

首先我们 git init 生成一个新的仓库。

git 会自动创建如下目录:在 git 的对象数据库中,创建了一个新的文件。

这个文件的内容是 README.md 的内容,文件名是其 sha1 后 base16 编码的字符串。

注意这里用了两层目录结构,这样在有很多对象的时候不至于目录内容太多而过载。这样的设计模式在很多系统中都可以见到,比如 nginx cache。

git 内部主要有四种对象:

blob:对象存储实际的文件

tree:对象存储文件的目录结构

commit:对象存储提交信息(主要是当前的树根和上一棵树的树根)

tag:存储版本信息,相当于对对象库中的某个 commit 显式标记了一下文件的文件名并没有存在 blob 对象中,而是存储在 tree 里。这样有两个好处:1) 相同内容的文件,即便拷贝多份,依然只存储一份数据 — 这多见于二进制文件,比如图片;2) 更改文件名只是生成一个新的 tree,并不需要生成新的 blob 操作.

Git 配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

git config --global user.name "@username"
git config --global user.email "@email"
git config --global color.ui true
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global core.editor "mate -w"    # 设置Editor使用textmate
git config -l  # 列举所有配置用户的 git 配置文件

Git 常用命令

git init            # 将当前目录初始化为git仓库
git clone https://github.com/KKDestiny/wechat_oauth2.0.git # 克隆远程仓库到当前路径
git help <command>  # 显示command的help
git show            # 显示某次提交的内容
git show $id

git co  -- <file>   # 抛弃工作区修改
git co  .           # 抛弃工作区修改

git add <file>      # 将工作文件修改提交到本地暂存区
git add .           # 将所有修改过的工作文件提交暂存区

git rm <file>       # 从版本库中删除文件
git rm <file> --cached  # 从版本库中删除文件,但不删除文件

git reset <file>    # 从暂存区恢复到工作文件
git reset -- .      # 从暂存区恢复到工作文件
git reset --hard    # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改

git ci <file>
git ci .
git ci -a           # 将git add, git rm和git ci等操作都合并在一起做
git ci -am "some comments"
git ci --amend      # 修改最后一次提交记录

git revert <$id>    # 恢复某次提交的状态,恢复动作本身也创建了一次提交对象
git revert HEAD     # 恢复最后一次提交的状态
查看文件diff

git diff <file>     # 比较当前文件和暂存区文件差异
git diff
git diff <$id1> <$id2>   # 比较两次提交之间的差异
git diff <branch1>..<branch2> # 在两个分支之间比较
git diff --staged   # 比较暂存区和版本库差异
git diff --cached   # 比较暂存区和版本库差异
git diff --stat     # 仅仅比较统计信息
查看提交记录

git log
git log <file>      # 查看该文件每次提交记录
git log -p <file>   # 查看每次详细修改内容的diff
git log -p -2       # 查看最近两次详细修改内容的diff
git log --stat      # 查看提交统计信息

Git 提交代码规范

<type>(<scope>): <subject>

1. type
feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动

2. scope
用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
db 、controller 、views

3. subject
是 commit 目的的简短描述,不超过50个字符。
"模块:弹框"

Git 忽略文件格式

  # Created by .ignore support plugin (hsz.mobi)
  ### Java template
  *.class

  # Mobile Tools for Java (J2ME)
  .mtj.tmp/
  .logs/*
  **/*.iml
  # Package Files #
  *.jar
  *.war
  *.ear
  target
  .idea
  .DS_Store
  exports
  # virtual machine crash logs, see
  http://www.java.com/en/download/help/error_hotspot.xml
  hs_err_pid*
  .tags
  .tags_sorted_by_file

Git 本地分支管理

git br -r           # 查看远程分支
git br <new_branch> # 创建新的分支
git br -v           # 查看各个分支最后提交信息
git br --merged     # 查看已经被合并到当前分支的分支
git br --no-merged  # 查看尚未被合并到当前分支的分支

git co <branch>     # 切换到某个分支
git co -b <new_branch> # 创建新的分支,并且切换过去
git co -b <new_branch> <branch>  # 基于branch创建新的new_branch

git co $id          # 把某次历史提交记录checkout出来,但无分支信息,切换到其他分支会自动删除
git co $id -b <new_branch>  # 把某次历史提交记录checkout出来,创建成一个分支

git br -d <branch>  # 删除某个分支
git br -D <branch>  # 强制删除某个分支 (未被合并的分支被删除的时候需要强制)

Git 远程分支管理

git pull                         # 抓取远程仓库所有分支更新并合并到本地
git pull --no-ff                 # 抓取远程仓库所有分支更新并合并到本地,不要快进合并
git fetch origin                 # 抓取远程仓库更新
git merge origin/master          # 将远程主分支合并到本地当前分支
git co --track origin/branch     # 跟踪某个远程分支创建相应的本地分支
git co -b <local_branch> origin/<remote_branch>  # 基于远程分支创建本地分支,功能同上

git push                         # push所有分支
git push origin master           # 将本地主分支推到远程主分支
git push -u origin master        # 将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)
git push origin <local_branch>   # 创建远程分支, origin是远程仓库名
git push origin <local_branch>:<remote_branch>  # 创建远程分支
git push origin :<remote_branch>  #先删除本地分支(git br -d <branch>),然后再push删除远程分支
Git远程仓库管理
git remote -v                    # 查看远程服务器地址和仓库名称
git remote show origin           # 查看远程服务器仓库状态
git remote add origin git@github:robbin/robbin_site.git         # 添加远程仓库地址
git remote set-url origin git@github.com:robbin/robbin_site.git # 设置远程仓库地址(用于修改远程仓库地址)
git remote rm <repository>       # 删除远程仓库
创建远程仓库

git clone --bare robbin_site robbin_site.git  # 用带版本的项目创建纯版本仓库
scp -r my_project.git git@git.csdn.net:~      # 将纯仓库上传到服务器上

mkdir robbin_site.git && cd robbin_site.git && git --bare init # 在服务器创建纯仓库
git remote add origin git@github.com:robbin/robbin_site.git    # 设置远程仓库地址
git push -u origin master                                      # 客户端首次提交
git push -u origin develop  # 首次将本地develop分支提交到远程develop分支,并且track

git remote set-head origin master   # 设置远程仓库的HEAD指向master分支
也可以命令设置跟踪远程库和本地库

git branch --set-upstream master origin/master
git branch --set-upstream develop origin/develop

git branch 查看本地所有分支
git status 查看当前状态
git commit 提交

git commit -am "init" 提交并且加注释
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上
git remote show origin 显示远程库origin里的资源
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联
git checkout --track origin/dev 切换到远程dev分支

git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m "remove" 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新

Git 分支合并和 rebase

git merge <branch>               # 将branch分支合并到当前分支
git merge origin/master --no-ff  # 不要Fast-Foward合并,这样可以生成merge提交

git rebase master <branch>       # 将master rebase到branch,相当于:
git co <branch> && git rebase master && git co master && git merge <branch>

Git 补丁管理

git diff > ../sync.patch         # 生成补丁
git apply ../sync.patch          # 打补丁
git apply --check ../sync.patch  # 测试补丁能否成功

Git 暂存管理

git stash                        # 暂存
git stash list                   # 列所有stash
git stash apply                  # 恢复暂存的内容
git stash drop                   # 删除暂存区

总结

提交操作
git fetch origin master   #拉取远程代码到 init 之后的 master 主干上
git commit -am "fist"     #修改代码之后,提交到自己的仓库
git push -u mine master #提交到master代码库

git add .
git commit -m "注释文字" 只有三种状态:已修改、已暂存和已提交,git add 的作用就是将本地已修改状态的文件改变为已暂存,从而可以被提交(commit)到本地仓库。
git commit -a -m "注释文字"
git commit -am "注释文件"
git push origin lc_dev1.0


删除分支
git branch -d branch_name
git push origin :branch_name

切换分支
git checkout branch_name

添加分支
git branch branch_name

查看分支
git branch -va

合并分支
git branch -a 查看所有的分支
git branch -r 查看远程所有分支
git branch -D master develop 删除本地库develop

版本回退
git reset --hard HEAD~n 直接回退到前第 n 个版本。
git log
git relog
git reset HEAD filename  # 从暂存区移除文件
git reset --hard SHA #回到 SHA 对应的 commit 的版本。

比较版本不同
git diff HEAD~1 HEAD #比较上一次和这一次代码之间的差异

堆栈操作
git stash #创建堆栈临时缓存区
git stash list #查看 stash 栈堆
git stash pop #还原堆栈中的信息
git stash clear #清空场景(stash)堆栈。
git stash push 将文件给push到一个临时空间中
git push -u origin master -f 强制上传替换掉原有的数据
git stash pop 将文件从临时空间pop下来

重命名分支
git branch -m main master
git push -u origin master

## 删除原来的main 分支
git push origin --delete main