git

  • git
约 3756 字

git 命令查询

git 指令作用
ssh-keygen -t rsa -C <email>创建 SSH Key,位置位于%HomePath%/.ssh 目录,其中的 id_rsa 为私钥,id_rsa.pub 为公钥 (公钥为 github 填入的参数)
ssh -v git@43.139.179.52 ssh -vT git@github.comssh 远程连接指定服务器,用于查看调试信息
git config --global user.name "noby"设置全局用户名 (其配置的位置位于%HomePath%.gitconfig)(--global 表示全局,所有的全局配置将写进%HomePath%.gitconfig)
git config --global user.email "1326981297@qq.com"设置全局邮箱 (其配置的位置位于%HomePath%.gitconfig)
git config --global user.name显示用户名
git config user.name "noby"设置局部用户名 (当前文件夹)(仓库级别 --local(默认不写),本地配置将写进.git/.gitconfig)
git init获取本地仓库,生成.git 文件夹
git status查看文件的状态
Untracked files: 表示工作区的该文件不存在暂存区中
Changes not staged for commit: 表示工作区的该文件与暂存区中的该文件不同
Changes to be committed: 表示暂存区的文件与本地库的该文件不同
nothing to commit, working tree clean: 表示工作区、暂存区、本地库的文件都相同
Your branch is ahead of <name>/<branch> by 1 commit: 表示远程库 <name>/<branch> 的文件与本地库的该文件不同
git add <file>将工作区文件添加到暂存区由 git 管理,开始跟踪(track),被添加到暂存区的文件将会一直在暂存区,除非工作区的该文件删除或者使用 git rm --cached <file> 删除暂存区的该文件,多次添加同一文件的不同版本只是在这基础上更新
git commit -m <message>将暂存区提交到本地仓库
git diff <file>查看工作区文件相对于暂存区文件的不同
git diff HEAD -- <file>查看工作区文件相对于本地库文件的不同
git ls-files -s``git cat-file -p查看暂存区的文件
git rm --cached <file>从暂存区删除某文件
git rm <file>从暂存区和工作区删除某文件
git checkout -- <file>将工作区的该文件恢复成与暂存区的该文件相同
git checkout <file>将工作区的该文件恢复成与本地库的该文件相同
git reset HEAD <file>将暂存区的该文件恢复成与本地库的该文件相同
git log查看提交日志
git log --pretty=oneline查看美化的提交日志
git config --global alias.l 'log --pretty=oneline --abbrev-commit --all --graph'设置 l 命令的 git 别名为:git log --pretty=oneline --abbrev-commit --all --graph,(--global 表示全局,所有的全局配置将写进%HomePath%.gitconfig) (全局级别 --global 配置,仓库级别 --local(默认不写)、系统级别 --system 亦如此)
git config --global -l | grep alias 查看所有的 git 别名
git config --unset --global alias.l取消 l 命令的 git 别名
git reset --hard commitID目前的本地库版本退回到指定版本库版本(commitID 提交日志中查看)(--hard 表示将工作区和暂存区的该文件一并退回)
git reset --hard HEAD^目前的本地库版本退回到上一个版本库版本 (HEAD^^表示上 2 个,HEAD~num 表示上 num 个)
git reflog查看已经删除的提交记录(版本退回后,之后版本的提交日志会被删除,可以通过该方法查看)
.gitignore文件中输入忽略的文件名或文件夹名(后加/),可以不纳入 git 的管理,即为在 add 的阶段忽略该文件或文件夹从工作区添加到暂存区。但.gitignore 中的忽略配置将不会删除,已经添加到暂存区的文件或文件夹 (可通过 git rm --cached <file> 删除)
git branch查看分支列表及当前分支
git branch <branch>新建分支 <branch>
git checkout <branch>
git switch <branch>
切换分支 <branch>(switch 为新的指令)。当切换分支的时候,Git 会用 <branch> 分支的最后提交的快照替换你的工作区和暂存区的内容。当工作区或暂存区相对当前分支有新的内容时存在不可切换和可切换的两种情况。一,当两个分支文件完全相同时,可以切换,并在行底给出 M <file> 提示;二,当两个分支的文件不完全相同时,不可以切换,提示需要将工作区和暂存区的文件 stash(文件相同不一定 commitID 相同)
git checkout -b <branch>
git switch -c <branch>
创建并切换分支 <branch>
git merge <branch>合并分支<branch> 到当前分支:将更新当前分支的内容为当前分支和 <branch> 分支的合并分支,而 <branch> 分支保持不变。合并的原则是同时保留当前分支和 <branch> 分支相对历史共同节点的改动部分;若两分支都存在对共同节点的同一部分的改动,则需要执行手动解决冲突,然后 add 和 commit。若两分支不存在对共同节点的同一部分的改动,则 git 将会执行快速合并,并自动 add 和 commit
快速合并: 若两分支不存在对共同节点的同一部分的改动,将执行快速合并,且 <branch> 上相对共同节点的修改部分将代替当前分支的对应部分
解决冲突: 当两分支都存在对共同节点的同一部分的改动则需要手动解决冲突,git 会将两个分支的冲突部分汇总到工作区的该文件中,修改工作区文件解决掉冲突后还需 add 和 commit 到当前分支,至此当前分支的冲突解决完成,
git merge --no-ff <branch>使用非快速合并自动合并,需要输入 commit 消息
git log --graph查看分支合并图
git merge --abort解决合并冲突的过程中取消合并分支
git branch -d <branch>删除分支 <branch>
git stash储藏目前分支的暂存区和工作区的工作现场
git stash list查看工作现场
git stash apply <stash>恢复工作现场到当前分支 (不会删除储藏的该工作现场)(非当前分支的工作现场也可也恢复到当前分支)
git stash drop <stash>删除工作现场
git stash pop恢复工作现场到当前分支,同时删除储藏的该工作现场 (非当前分支的工作现场也可也恢复到当前分支)
git cherry-pick <commit>当两个分支来自同一个节点时,可复制一个分支 commit 到当前分支 (对当前分支做同样的 commit)
git tag <name>标记在当前分支当前点标签
git tag <name> <commitID>在指定 commitID 打标签
git tag查看标记的所有标签 (标签不是按时间顺序列出,而是按字母排序的。)
git tag -a <tagname> -m <message>书写标签详情
git show <tagname>查看标签信息
git tag -d <tagname>删除指定标签
git push <name> <tagname>推送 <tagname> 标签到 <name> 远程库 (默认未指定推送标签是不会把标签推送到远程)
git push <name> --tags推送所有标签到 <name> 远程库
git push <name> :refs/tags/<tagname>删除 <name> 远程的 <tagname> 标签 (前提是删除本地的 <tagname> 标签)
git remote查看远程库列表
git remote -v当前远程库的信息
git remote add <name> <url>添加远程库 <name> 为远程库的名,一般为 origin。<url> 为远程库的地址 (<name> 为本地库为方便关联远程库的 url 而存在的,使用 <name> 为了在本地使用别名操作该 url)
git remote set-url <name> <url>可以修改已经存在的 <url>,url 分为 https 和 ssh 两种,推荐使用 ssh
git remote rm <name>解除本地库和远程库 <name> 的关系,并不是物理上删除了远程库
git push (-u) <name> <branch>将本地库的当前分支推送到 <name> 远程库的 <branch> 分支,并且将会在远程库自动合并当前分支到 <name>/<branch> 分支。(-u 表示将远程分支 <name>/<branch> 与当前分支关联)
git push <name> <branch> -f强制推送到远程仓库 (一般为将远程某分支的版本回退)
git push --all <name> -f 将本地的所有分支强制推送到远程 (一般为远程库的第一次初始化)
git config --global --add push.default current 设置 Git 在执行  git push  命令时,如果没有指定分支名称,则默认推送当前分支。
git config --global --add push.autoSetupRemote true 设置 Git 在执行  git push  命令时,如果当前分支没有关联的远程分支,则自动关联一个同名的远程分支。
git pull将远程分支的对应当前分支拉取到工作区 (前提是已经关联当前分支到远程分支),同时合并 (满足快速合并会执行快速合并)
git fetch从远程获取最新版本到远程仓库副本,同 pull 的区别在于 fetch 不会自动 merge. 而 git pull 是从远程获取最新版本并 merge 到本地仓库. 从安全角度出发,git fetch 比 git pull 更安全,因为我们可以先比较本地与远程的区别后,选择性的合并。通常用于查看其他人正在处理的内容进度
git pull = git fetch + git merge
git clone <url>克隆远程的 url 项目,到当前的路径,注意会在操作 git 的目录下创建远程项目相同的项目目录
git branch --set-upstream-to=<name>/<branch> <branch>将远程分支与本地分支关联
git branch -v查看本地和远程关联的分支
git rebaserebase 操作可以把本地未 push 的分叉提交历史整理成直线
在 push 某本地分支到远程分支之前,该远程分支若有改变,应先 pull 到本地 merge,再 push 到远程让 github 自动合并。但这样做会在本地新建一条用于存放 pull 下来的分支,该分支用于和本地分支 merge。该多余的分支 rebase 命令优化。优化的原理把 merge 的过程调整到本地分支的改动之前,这样便不必创建新的分支

git 项目的结构

  • 项目目录
    • .git 文件夹
      • 本地仓库 (版本库)(Repository)
        • 指针
          • HEAD
        • 分支
          • master 分支
            • commit 时间线
              • commitID3(HEAD 指向的)
              • commitID2
              • commitID1
          • A 分支
            • commit 时间线
      • 暂存区 (Stage、index)
    • 工作区 (working tree)
  • 远程仓库 (remote)
    • 分支
      • master 分支
        • commit 时间线
          • commitID3
          • commitID2
          • commitID1
      • A 分支
        • commit 时间线

image-20221103132542796image-20221104222117421

git 的网络代理

git 克隆 github 的仓库一般较慢,可以使用 clash 代理

  • 若使用 https 或 http 克隆仓库可以在.gitconfig 配置 https、http 的代理: git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy https://127.0.0.1:7890
  • 若是使用 ssh 克隆仓库,则可以通过配置~/.ssh/config 文件
Host github.com
  User git
  ProxyCommand nc -v -x 127.0.0.1:7890 %h %p

.git 文件夹的空间优化

  • git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 --reverse | head -n 10 列出占用空间大小的前 10 排序
  • git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *.pdf' --prune-empty --tag-name-filter cat -- --all 删除所有的 pdf 文件
  • rm -rf .git/refs/original/ 删除 Git 仓库中的原始引用(refs/original/)。原始引用是在执行 Git 的一些操作(如 git filter-branch)时自动生成的备份引用。删除原始引用可以清理 Git 仓库中不再需要的备份数据。
  • git reflog expire --expire=now --all 清理 Git 的引用日志(reflog)。引用日志记录了 Git 仓库中的引用(分支、标签等)的变更历史。通过指定 --expire=now 参数,可以将所有引用日志的过期时间设置为当前时间,从而清除所有引用日志。
  • git gc --prune=now 运行 Git 的垃圾回收(garbage collection)命令。垃圾回收会清理 Git 仓库中的无效对象和不再需要的数据,从而优化存储空间。通过指定 --prune=now 参数,可以立即执行垃圾回收,并删除所有不再需要的对象。
  • git push --force --all 最后执行 git 的强制推送,使得远程仓库会被当前优化后的本地仓库覆盖

将服务器设置为 git 的远程库

  # 添加一个名为 git 的用户
  adduser git
  # 设置 git 用户的密码
  passwd git
  # 提权
  sudo visudo
  # 在文件里写入
  git ALL=(ALL:ALL) ALL
  # 保存提出,然后切换到 git 用户
  su - git
  
  # 创建并进入代码仓库目录
  mkdir -p /home/www/website cd $_
  # 赋予 git 用户权限
  sudo chown git:git /home/www/website
  # 创建代码目录并进入
  mkdir ts.git && cd $_
  # 专门用来创建远程仓库的初始化,git仓库通常以*.git命名。这种仓库只包括 git 版本控制相关的文件,不含工作区(不设置hooks即为不能在远程库修改工作区)
  git --bare init
  # 所以我们需要借助一个 hooks,在有代码提交到该仓库的时候,将提交的代码迁移到其他目录,这里我们在 ts.git 同级目录下创建了一个 ts 文件夹,用于存放提交的源代码文件:
  # 进入 hooks 目录
  cd hooks
  # 创建并编辑 post-receive 文件
  vim post-receive
  # 这里是 post-receive 写入的内容
  #!/bin/bash
  git --work-tree=/home/www/website/ts checkout -f
  # 赋予执行权限
  chmod +x post-receive
  # 退出目录到 ts.git 同级目录并创建文件
  cd ../../ && mkdir ts
  
  # 推送到该远程库
  git push -f -u git@192.168.122.128:/home/www/website/ts.git master
  
  # 设置远程库的公钥
  # 进入主目录
  cd /home/git
  # 进入 .ssh 目录
  cd .ssh
  # 创建 authorized_keys 文件,写入公钥(本地位于~/.ssh/id_rsa.pub)
  vim authorized_keys
  # 给相关文件添加执行权限
  chmod 600 /home/git/.ssh/authorized_keys
  chmod 700 /home/git/.ssh

其他注意事项

  • 当本地仓库的版本低于远程仓库的版本时,应该先拉取远程仓库的版本,再推送本地版本
  • 任何文件的增删改(包括合并分支)都是在本地仓库进行,然后在推送到远程仓库
  • 新建项目没配置 gitignore 文件,导致 node_modules 文件上传到了 git 仓库。.gitignore 文件为忽略还未从工作区添加到暂存区的文件,对于已经推送到远程仓库的 node_modules,暂存区中已经存在,直接在.gitignore 文件中写入该 node_modules 并不会删除暂存区中的 node_modules,因此需要使用命令删除暂存区中的 node_modules.下面是解决方法,可以删除仓库已上传的 node_modules 文件:
 git rm -r --cached node_modules
 git commit -m 'delete node_modules file'
 git push origin master