本文最后更新于 2024-07-16,文章内容可能已经过时。

Git最初由林納斯·托瓦斯创作,於2005年以GPL授權條款发布,最初的目的只是为了更好的管理Linux的内核开发而设计。现在已经成为目前最流行的分布式版本控制系统,它功能强大,命令繁多。今天在这篇文章里罗列一些常用的git 命令。

Git的几个基本概念

  • git本地由三个部分组成:工作区 和 暂存区 和 本地库。
  • .git目录才是仓库的灵魂,.git目录里面包括 暂存区 和 本地库,.git目录外的地方是工作区。
  • git中包含4类对象 (commit 提交对象, tree 目录, blob 文件, tag 标记)

git模型

  • 工作区 = working directory
  • 暂存区 = snapshot/stage/index
  • 本地库 = local repo

.git目录

  • HEAD 指向当前分支
  • config 项目配置文件
  • description 供GitWeb程序使用
  • hooks/ 客户端与服务端钩子脚本
  • info/ 忽略模式
  • index 暂存区域信息
  • objects/ 所有数据内容
  • refs/ 指向所有commit的指针

.gitignore
需要被Git系统忽略的文件(夹),可以写在 .gitignore文件里,支持通配符,比如:

*.o
*.log
build/
.svn/

git 提交代码步骤

# 查看当前工作区和暂存区的📃文件状态
git status

# 把本次需要提交的文件添加到暂存区
git add $file_name1 $file_name2 $file_name3

# 使用commit命令添加文件到本地仓库
git commit -m "commit message"

# 推送到远程仓库,假设要推送的远程分支名为: develop。
git push origin HEAD:refs/for/develop

[!CAUTION]⚠️

第4步推送代码到远程仓库,不同的代码托管平台可能会有不同的推送指令,比如有gitlab版本开发者推送的是 自己新创建的分支,然后评审完毕以后,在远端把分支merge到开发分支或者主分支。 所以这一步请 结合自己所使用代码托管平台的设置执行与之相对应的操作。

git 常用命令

# 只克隆最近1次commit
git clone --depth=1 repo_url.git

# example: 
# git clone -b release-1.9 --depth=1 git@github.com:apache/flink.git

# 添加远程仓库地址
git remote add itwild git@github.com:itwild/rewild.git

# 查看远程仓库地址
git remote -v

# 显示工作区和暂存区的状态:修改、新增了哪些文件,当前所在的分支等
git status

# 添加 文件file到暂存区,准备提交
git add $file_path1 $file_path2

# 添加当前目录及其子目录下所有修改过的和新增的文件📃到暂存区
git add -A   # git add .  也实现同样功能

# 将暂存区的更改提交到本地仓库,并附带本次提交的 提交信息
git commit -m "commit message ..."

# 将本地当前分支推送到远程itwild仓库的master分支
git push itwild master

# 强推(需要关闭对分支的保护),该操作需要谨慎
git push -f itwild master

# 修订上次的提交
git commit --amend

# 修订上次的提交时间
git commit --amend --date="1 minute ago"

# 指定commit时间
git commit --date="10 day ago" -m "Your commit message" 

# 调整前几次的提交
git rebase -i HEAD~2

# 从itwild远程仓库拉取最新的代码(仅仅是拉取代码,并没有参与本地分支merge或者rebase操作)
git fetch itwild

# 展示本地分支的提交历史
git log

# 展示远程分支itwild/master的提交历史
git log itwild/master

# 可取代merge操作,避免产生不必要的commit,破坏提交树的美观
# 找到两条分支的共同祖先,然后将共同祖先后不同的提交,回放一遍。
git rebase itwild/master

# 本地所有修改的,没有的提交的,都返回到原来的状态
git checkout . 
# 把所有没有提交的修改暂存到stash里面。可用git stash pop恢复
git stash

# 返回到某个commit,不保留修改
git reset --hard commit_id

# 返回到某个commit,保留修改
git reset --soft commit_id

从工作目录中删除所有没有tracked过的文件

git clean 参数
    -n  Don't actually remove anything, just show what would be done
    -f  --force  If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to delete files or directories unless given -f, -n or -i. Git will refuse to delete directories with .git sub directory or file
           unless a second -f is given.
    -d  Remove untracked directories in addition to untracked files复制请点击Error复制成功

cherry-pick某个提交

git cherry-pick [<options>] <commit-ish>...

常用options:
    --quit                退出当前的chery-pick序列
    --continue            继续当前的chery-pick序列
    --abort               取消当前的chery-pick序列,恢复当前分支
    -n, --no-commit       不自动提交
    -e, --edit            编辑提交信息

git tag

# https://github.com/apache/flink/tags

# https://www.liaoxuefeng.com/wiki/896043488029600/902335479936480

# 本地打tag
git tag -a release-1.11.2 -m 'Apache Flink 1.11.2'

# 删除一个本地标签
git tag -d <tagname>

# 推送一个本地标签到远程仓库
git push itwild <tagname>

# 推送全部未推送过的本地标签
git push itwild --tags

# 删除一个远程标签
git push itwild :refs/tags/<tagname>

git子模块 (submodule)

项目中可能会使依赖一些公共库或者其他team维护的其他项目,git submodule就可以很方便解决这样的场景。 使用子模块后,不必负责子模块的维护,只需要在必要的时候同步更新子模块即可。

# 递归克隆包含子模块的项目
git clone --recursive <repository>

# 添加子模块
git submodule add [repo]

git submodule init
git submodule update --init --recursive
git submodule update --remote --recursive

git submodule foreach 'git pull'
git submodule foreach 'git checkout -b featureA'
git submodule foreach 'git diff'

git 配置多个SSH-Key

参考:https://my.oschina.net/stefanzhlg/blog/529403

日常工作中会遇到公司有个gitlab,还有些自己的一些项目放在github上。这样就导致我们要配置不同的ssh-key对应不同的环境。具体操作如下:

  1. 生成一个公司用的SSH-Key

    ssh-keygen -t rsa -C "youremail@yourcompany.com" -f ~/.ssh/gitlab-rsa复制请点击Error复制成功
    

    在~/.ssh/目录会生成gitlab-rsa和gitlab-rsa.pub私钥和公钥。 我们将gitlab-rsa.pub中的内容粘帖到公司gitlab服务器的SSH-key的配置中。

  2. 生成一个github用的SSH-Key

    ssh-keygen -t rsa -C "youremail@your.com" -f ~/.ssh/github-rsa复制请点击Error复制成功
    

    在~/.ssh/目录会生成github-rsa和github-rsa.pub私钥和公钥。 我们将github-rsa.pub中的内容粘帖到github服务器的SSH-key的配置中。

  3. 添加私钥

    ssh-add ~/.ssh/gitlab-rsa
    ssh-add ~/.ssh/github-rsa复制请点击Error复制成功
    

    如果执行ssh-add时提示"Could not open a connection to your authentication agent",可以现执行命令:ssh-agent bash,然后再运行ssh-add命令。

    # 可以通过 ssh-add -l 来确私钥列表
    ssh-add -l
    # 可以通过 ssh-add -D 来清空私钥列表
    ssh-add -D复制请点击Error复制成功
    
  4. 修改配置文件

    在 ~/.ssh 目录下新建一个config文件

    touch config复制请点击Error复制成功
    

    添加内容:

    # gitlab
    Host gitlab.com
     HostName gitlab.com
     PreferredAuthentications publickey
     IdentityFile ~/.ssh/gitlab-rsa
    # github
    Host github.com
     HostName github.com
     PreferredAuthentications publickey
     IdentityFile ~/.ssh/github-rsa复制请点击Error复制成功
    
  5. 测试

    # test your company gitlab
    ssh -T git@yourcompany.com
    # test github
    ssh -T git@github.com
    

git对某个项目单独设置用户名/邮箱

  1. 进入项目.git文件夹,然后执行如下命令分别设置用户名和邮箱

    git config user.name "bytesfly"
    git config user.email "bytesfly@example.com"
    #使用vim作为编辑器
    git config --global core.editor "vim"复制请点击Error复制成功
    
  2. 然后可以查看生成的config文件

    cat config
    

git设置代理

取消代理:

git config --global --unset http.proxy
git config --global --unset https.proxy复制请点击Error复制成功

设置代理:

git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'复制请点击Error复制成功

仅代理 GitHub

git config --global http.https://github.com.proxy socks5://127.0.0.1:1080

# 取消代理
git config --global --unset http.https://github.com.proxy

git的学习网站