Git

1 简介

2 命令

2.1 git clone

1
git clone url <directory-name> # 将拉下来的仓库文件夹重命名

2.2 git add

1
2
3
git add .               # 暂存所有修改
git add <file> # 暂存某个文件
git add --patch <file> # 生成 patch

2.3 git commit

1
2
3
4
5
git commit --amend                          # 将暂存的修改与上一个提交合并
git commit --no-edit # 不修改内容
git commit --no-edit --author="name<email>" # 修改上一个提交的作者
git commit --amend --edit # 修改 commit 信息
git commit --fixup=<Hash> # 将修改作为补丁提交

2.4 git pull

1
git pull origin --rebase # 拉取远程分支并 rebase

2.5 git push

1
2
3
4
git push -f origin
git push --delete origin <branch> # 删除远程分支
git push <remotename> <commit SHA>:<remotebranchname>
git push origin 123456:refs/heads/branch

2.6 git fetch

1
git fetch origin

2.7 git rebase

1
2
git rebase -i <Hash>
git rebase --autosquash -i <Hash>

2.8 git remote

1
2
3
4
git remote -v
git remote show origin
git remote prune origin
git remote set-url dev ssh://git@host:port/~/xxx.git

2.9 git cherry-pick

2.10 git diff

commit_A: 前一次提交的 hash 值。
commit_B: 需要导出位置的提交的 hash 值。
git diff commit_A commit_B > patch.patch
注:导出的 patch 文件是两个提交信息之间所有的差异。

2.11 git log

2.12 git show

2.13 git branch

1
git branch -m <old name> <new name> # 修改本地分支名

2.14 git config

1
git config --global init.defaultBranch <defaultBranch> # 设置默认分支名

3 进阶操作

3.1 Git global setup

1
2
git config --global user.name "xxx"
git config --global user.email "xxx@zzz.com"

3.2 Create a new repository

1
2
3
4
5
6
git clone git@github.com:xxx/xyz.git
cd xyz
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master

3.3 Push an existing folder

1
2
3
4
5
6
cd existing_folder
git init
git remote add origin git@github.com:xxx/xyz.git
git add .
git commit -m "Initial commit"
git push -u origin master

3.4 Push an existing Git repository

1
2
3
4
5
cd existing_repo
git remote rename origin old-origin
git remote add origin git@github.com:xxx/xyz.git
git push -u origin --all
git push -u origin --tags

3.5 忽略更改

  • .gitignore

    • 说明:显式地阻止提交文件。
    • 优势:.gitignore 文件本身提交至远程仓库,全组共享忽略文件配置。
    • 局限:如果项目已经存在远程仓库,即使被加入 .gitignore,仍然可以进行修改并提交。本地的修改会显示在 git status 结果中。
  • .git/info/exclude

    • 说明:显式地阻止提交文件。
    • 优势:exclude 文件本身不会提交至远程仓库,因此适合放一些个人定制的「gitignore」项目。
    • 局限:和 .gitignore 存在同样地局限。文件若已存在远程仓库,则本地修改仍可以提交至远程仓库。本地的修改会显示在 git status 结果中。
  • assume-unchanged

    • 说明:声明本地远程都不会修改这个文件。
    • 优势:git 直接跳过这些文件的处理以提升性能。文件不会出现在 git status。
    • 局限:不适合本地或远程需要修改的文件。本地会忽略掉之后远程文件的修改。
    1
    git update-index --assume-unchanged
  • skip-worktree

    • 说明:声明忽略文件的本地修改。
    • 优势:本地可以对文件做一些个人定制。文件不会出现在 git status。
    • 局限:拉取远程文件更新,或切换分支时有可能出现冲突,需要撤销忽略后手动解决冲突。
    1
    git update-index --assume-unchanged

3.6 设置跟踪关系

  • 新建一个分支并设置跟踪关系

    1
    git checkout -b new_branch_name [--track] origin/remote_branch_name # --track 选项可以省略
  • 设置已有分支和远端分支的跟踪关系

    1
    2
    3
    git branch -u origin/remote_branch_name local_branch_name
    # or
    git branch --set-upstream-to=origin/branch_name local_branch_name

    -u 选项是 –set-upstream-to 的简写;
    local_branch_name 可以省略,默认值为当前分支。

3.7 通过哈希值查找提交

1
2
git log <Hash>
git show <Hash>

3.8 修改分支名

1
2
3
git push --delete origin <branch>   # 删除远程分支
git branch -m <old name> <new name> # 修改本地分支名
git push origin <new branch> # 推送本地分支

3.9 创建 git 仓库

1
2
git init --bare aaa.git # 创建远程仓库
git init aaa # 创建本地仓库

3.9.1 配置环境

  1. 安装apt install git
  2. 创建用户adduser git
  3. 设置仓库默认分支名git config --global init.defaultBranch main
  4. 创建证书登录
    将需要登录用户的公钥,默认为~/.ssh/id_rsa.pub,导入到/home/git/.ssh/authorized_keys,一行一个。
    cat .ssh/id_rsa.pub >> /home/.git/.ssh/authorized_keys
  5. 初始化 Git 仓库
    --bare会创建一个裸仓库,裸仓库没有工作区,因为服务器上的 Git 仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的 Git 仓库通常都以.git 结尾。
    git init --bare project.git
    然后,把 owner 改为 git:
    chown -R git:git project.git
  6. 修改远程仓库默认分支名
    cd project.git && git symbolic-ref HEAD refs/heads/main
  7. 禁用 shell 登录
    出于安全考虑,不允许 git 用户登录 shell,修改/etc/passwdgit:x:6666:6666:,,,:/home/git:/bin/bashgit:x:6666:6666:,,,:/home/git:/bin/git-shell
  8. 拉取仓库
    git clone git@server:xxx/project.git

3.9.2 管理权限

  • 要方便管理公钥,用 Gitosis
  • 要像 SVN 那样变态地控制权限,用 Gitolite

3.9.3 配置空仓库

  • Git global setup

    1
    2
    git config --global user.name "Laplace"
    git config --global user.email "Laplac2@outlook.com"
  • Create a new repository

    1
    2
    3
    4
    5
    6
    git clone git@gitlabwh.uniontech.com:ut000893/test.git
    cd test
    touch README.md
    git add README.md
    git commit -m "add README"
    git push -u origin master
  • Push an existing folder

    1
    2
    3
    4
    5
    6
    cd existing_folder
    git init
    git remote add origin git@gitlabwh.uniontech.com:ut000893/test.git
    git add .
    git commit -m "Initial commit"
    git push -u origin master
  • Push an existing Git repository

    1
    2
    3
    4
    5
    cd existing_repo
    git remote rename origin old-origin
    git remote add origin git@gitlabwh.uniontech.com:ut000893/test.git
    git push -u origin --all
    git push -u origin --tags

3.10 子模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git remote set-head origin -a # 设置 HEAD
# add
git submodule add git@github.com:aaa/xxx.git # 添加子模块
git submodule add -b <branch> --name <name> <repo-url> <local dir> # 添加子模块
git config -f .gitmodules submodule.xxx.branch main # 设置默认分支
git submodule set-url xxx git@github.com:aaa/xxx.git # 设置子模块仓库地址
git submodule sync --recursive # 同步配置文件到本地
git submodule update --init --recursive # 递归更新仓库
git submodule update --remote --rebase
git submodule update --remote --merge
# remove
git submodule deinit <submodule_path> # 删除本地配置 .git/config
rm -rf .git/modules/<submodule_path>
git rm -f <submodule_path> # 删除子模块配置 .gitmodules

4 git lfs

  • 安装 git lfs
1
2
3
sudo apt install git-lfs
git lfs install
git lfs track "*.psd"
  • 移除 git lfs
1
2
3
4
5
6
git lfs pull
# or
git lfs fetch
rm .gitattributes
git rm --cached -r *
git add .

5 参考文献


Git
https://laplac2.github.io/tools/git/
作者
Laplace
发布于
2021年12月1日
许可协议