Back

Git常用命令

Git常用的一些命令,需要Git基础,方便查阅。

注意:要学会使用-h –help选项,查看命令,看不懂在查阅。git help <command>可进入官方文档。Git入门参考。以下常用命令个人收集总结。


git简单命令

git init

  • git init <directory>在指定的⽬录下创建⼀个空的git repo。不带参数将在当前⽬录下创建⼀个git repo。

git clone

  • git clone <repo>克隆⼀个指定repo到本地。指定的repo可以是本地⽂件系统或者由HTTP或SSH指定的远程路径。
  • git clone -b <branch> <repo>克隆指定仓库的分支
  • git clone --recursive <repo>递归地克隆,克隆带有子模块的仓库
    • git clone --recurse-submodules <repository_url>同理
  • 可组合使用

git add

  • git add <directory>将指定⽬录的所有修改加⼊到下⼀次 commit中。把<directory>替换成<file>将添加指定⽂件的修改。
  • git add *git add .git add -A三条命令但是一样的,将所以修改提交到暂存区。

git commit

  • 这个命令通常带-m选项git commit -m "<message>"提交暂存区的修改,使⽤指定的 <message>作为提交信息,⽽不是打开⽂本编辑器输⼊提交信息。
  • git commit -m <message> --amend将当前staged修改合并到最近⼀次的commit中。

git status

  • git status显示哪些⽂件已被staged、以及未跟踪(untracked)。

git reflog

  • git reflog显示本地repo的所有commit⽇志。
  • git log的区别
    1. log项目的提交历史,reflog本地仓库的引用提交日志。
    2. 引用会保留所以的提交历史,如何重置的历史。主要目的是提供一个安全网,以便在误操作(如错误的 git reset)后可以恢复丢失的提交或分支。
    3. git log 的输出是永久性的,而 reflog 会在一段时间后自动过期(默认是 30 天),以节省空间。

git rm

  • git rm fileName删除指定的文件。
    • rm fileName的区别。
      1. git rm不能删除未跟踪的文件,
      2. git rm删除之后直接到暂存区,而rm是到工作区
  • 注意删除之后都需要提交操作。
  • 撤销操作不用记,git都会有提示

git switch

  • 该命令适用于特定git版本。

  • git switch <branch>切换到指定分支,

    • git checkout <branch>同理,但这个都适用。
  • git switch -c <branch>创建并切换指定分支

git branch

  • git branch显示本地repo的所有分⽀。

    • -v显示详细信息
    • *的为当前分支
  • git branch -r显示远程仓库的所以分支。

    • 可以使用git checkout <branch>检出远程分支,可以省略origin/
  • git branch -a显示本地和远程的所有分支

  • git branch -m <old_branch_name> <new_branch_name>重命名分支

    • 新分支名已经存在, -M 强制重命名。
  • git branch <name>创建指定分支

  • git branch -D <branch>强制删除指定分支,无论是否合并到当前分支。

  • git branch -d <branch>删除指定的分支,如果没有合并到当前分支,git会阻止操作。

git merge

  • git merge <branch>合并指定分支。将指定<branch>分⽀合并到当前分⽀。
    • 是在当前分支合并指定分支。
    • 合并分支可能会出现冲突。要解决冲突之后才能合并。
  • git merge --abort放弃本次合并

git一般命令

git revert

  • git revert <commit> 对指定<commit>创建⼀个undo的commit,并应⽤到当前分⽀。就是撤销指定的提交并保留记录
    • 效果:撤销指定的提交,回到了撤销提交的是上个版本,保留了撤销历史会打开编辑器显示具体效果
    • 一般不用

git reset

  • git reset <commit>重置到指定的提交,不会保留commit历史。工作区和暂存区会变成未跟踪。--hard选项完全重置到指定提交。未跟踪的重置不了。重置历史可以通过git reflog查看,利用这个可以重置已经重置的版本库。

    • <commit>可以是:
      • HEAD表示最新的提交或者这个版本库,HEAD^、HEAD~1上上次提交或者上个版本
      • 或者使用commit_hash,提交的哈希值可以使用git log查看,只需要前几位就行。
  • git reset(重置到最新的提交)移除所有暂存区、工作区的修改,到未跟踪。这些命令其实省略了HEAD

    • git reset --hard 重置到最新的提交,删除工作区和暂存区

    • git reset <file><file>从暂存区移除,但保持⼯作区不变。此操作不会修改⼯作区的任何⽂件。

git restore

  • git restore <file>...撤销对工作区的修改,是对以跟踪的文件当未添加到暂存区的文件。多个文件用空格分开。
    • git checkout -- <file>...同理,--可以省略
  • git restore --staged <file>...撤销对暂存区的修改到未跟踪。针对添加到暂存区的文件。
    • git reset HEAD <file>...同理,HEAD可以省略。
  • 具体用哪一个,git都会有提示,不用记。

git checkout

  • git checkout <branch>切换到指定的分支

    • 如果分支为远程分支,则检出远程分支
  • git checkout -b <new-branch>切换并创建指定的分支

  • git checkout <file>撤销工作区的修改

    • git restore <file>同理
  • git checkout <commit>根据指定的提交创建一个分支,处于游离态。一般不用。

  • git checkout -b <local_branch_name> origin/<remote_branch_name>切换到远程分支

    • git checkout <branch>差不多,可以使用git fetch origin获取仓库所以信息,在检出分支。
  • git checkout -切换到前一个分支。

git remote

  • 用来管理远程仓库列表,origin为远程仓库的默认别名。这些远端仓库的信息都被保存在./git/config 文件中。

  • git remote列出所有已配置的远程仓库的信息。

    • -v显示详细信息
  • git remote add <remote_name> <remote_url>添加远程仓库

    • 添加⼀个新的远程连接。添加后可使⽤ <name>作为指定<url>远程连接的名称。
    • 只有配置了这个才能推送到远程仓库。
    • git remote rename <old_name> <new_name>重命名远程仓库。
    • git remote set-url <remote_name> <new_url>修改远程仓库的url。
    • git remote remove <remote_name>git remote rm <remote_name>删除远程仓库。
  • git remote show <remote_name>显示远程仓库的详细信息,包括 URL、跟踪的分支等。

  • 补充如何创建远程仓库

    1. 创建远程仓库可以先在github上创建好,然后在本地pull下来,在进行修改后push上去。

    2. 可以建一个空白仓库,在本地push上去,但需要进行绑定。

      1
      2
      3
      
      git remote add origin https://github.com/username/null-project.git
      git branch -M main
      git push -u origin main
      

gjit push

  • 将本地仓库推送到远程仓库

  • git push <remote_repository> <本地分支名>:<远程分支名>推送本地分支到指定的远程分支。如果远程分支不存在,会自动创建。:前后不能有空格。

    • 当分支同名,可以简写成git push <remote_repository> <本地分支名>
    • 果无法提交的话执行,-f--force选项强制推送,一般不用。
  • git push -u <remote_repository> <本地分支名>设置默认推送分支。

    • 作用:这样设置以后,推送到远程仓库可以简写成git push
      • git push 代替 git push origin master
    • -u--set-upstream的短形式。
  • git push <remote_repository> -d <远程分支名>删除远程分支 。

    • --delete长选项。
    • git push origin :test同理,没有写本地分支,就是删除远程分支。
  • git push <remote> <tagname>推送指定标签到指定远程仓库,一般为`origin``

  • ``git push –tags`推送所用标签到远程

git pull

  • git pull <remote_repository> <远程分支名>:<本地分支名>从远程仓库拉取最新代码到本地仓库。
    • git pull会拉取并合并,出现冲突要解决之后才能合并。
    • git fetch获取当前远程仓库的最新信息,不会合并。
    • 通常可以简写成git pull,远程仓库默认是origin,分支默认是当前分支。
  • git pull --rebase<remote> 抓取远程分⽀,并以rebase模式并⼊本地repo⽽不是merge。

git fetch

  • git fetch origin获取远程仓库最新的更改。不会合并。默认仓库是origin,分支是当前分支,这里可以省略origin
    • git fetch origin <branch>获取特定分支的更改.
  • git fetch --all获取所用仓库远程仓库的最新更改。
  • git pull的区别
    1. 都会获取远程仓库最新的更改。
    2. 但是fetch不会合并,而pull会合并。可以理解为git pullgit fetchgit merge 的组合
  • 获取最新更改之后可以:
    1. git checkout <branch>检出指定分支,如果加origin要这样git checkout -b <branch> origin/<branch>
    2. git merge origin/master合并远程 master 分支的更改到当前的分支
    3. git rebase origin/master使用 rebase 来整合更改(这可能会改变提交历史)

git stash

  • git stash保存工作区、暂存区,可以切换分支去完成别的任务。不保存修改,未提交的修改会错乱到别的分支。并且只能保存已追踪的文件。
  • git stash list查看保存的工作区以及暂存区。
  • git stash apply恢复保存的工作区以及暂存区。
    • 这个命令执行之后不会删除存储的工作区以及暂存区。
    • 要用git stash drop才能删除。
  • git stash pop恢复并删除保存的工作区以及暂存区。
  • 默认都是保存、恢复第一个stash即stash@{0}。若要指定第几个在后面加stash@{num}
    • 如恢复第二个stash:git stash pop stash@{1}
  • 每个分支共用一个stash。

git tag

  • 作用:用于标记项目的版本发布或重要的里程碑。
  • 分类
    1. git tag <tagname> <commit ID>轻量标签
      • git tag vn.n.n打标签,n.n.n表示对应的版本号,版本号前面一般加v,遵循一定的命名规范,如v1.0.1
        • 默认是打在最新的一次提交。
        • 后面跟提交的哈希值可以指定给那次提交打标签。如git tag v0.9.0 f52c633
          • 哈希值可以通过git log查看
    2. git tag -a <tagname> -m "<tag message>" <commit ID>附注标签
      1. git tag -a v0.1 -m "version 0.1 released" 1094adb
      2. 推荐id省略默认最新提交。
  • 查看标签
    1. git tag显示所有的本地tag列表,按照字母顺序排序。如果tag数量较多,可能会显示不全。省略选项-l--list
    2. git show <tagname>显示指定tag的详细信息,包括提交的作者、提交时间、提交信息等。
    3. git tag -n:显示tag列表,并同时显示每个tag对应的提交信息。
    4. git ls-remote --tags origin:显示远程仓库中的所有tag信息。更推荐这种。
      1. 或者先git fetch获取最新的更改,然后git tag检出所有标签。
  • 删除标签
    1. git tag -d <tagname>删除本地标签
    2. 删除远程标签:首先需要在本地删除标签,然后推送到远程仓库 git push origin :refs/tags/<tagname>
      1. 远程标签是refs/tags/v0.0.1这样存在的,跟删除远程分支差不多。
  • 标签一旦创建,就不能直接修改,如果需要修改标签,通常需要删除原标签,并重新创建一个新标签。
  • 推送标签
    1. 打的标签不会自动推送到远程仓库,需要手动推送。
    2. git push <remote> <tagname>推送指定标签到指定远程仓库,一般为origin
    3. git push <remote> --tags推送所用标签到远程

git复杂命令

git log

  • git log以缺省格式显示全部commit历史。更多⾃定义参数请参考后续部分。q退出,空格下一页,h查看帮助
    • git log --stat:显示详细的commit历史。
    • git log -<limit>限制log的显示数量。例如:”git log -5”仅显示最新5条commit。
    • git log --oneline每⾏显示⼀条commit,简化信息。与--pretty=oneline等效
    • git log --author= "<pattern>"按提交者名字搜索并显示commit。
    • git log --grep= "<pattern>"按指定内容搜索并显示commit。
    • git log <since>..<until>显示指定范围的commit。范围参数可以是commit ID、分⽀名称、HEAD或任意相对位置。
    • git log -- <file>仅显示包含指定⽂件修改的commit。
    • git log --graph使⽤–graph参数显示图形化的branch信息。

git diff

  • git diff⽐较⼯作区和暂存区的修改。
  • git diff HEAD⽐较⼯作区和上⼀次commit后的修改。
    • HEAD指向当前分支最新的commit版本库
  • git diff --cached⽐较暂存区和上⼀次commit后的修改。
  • git diff --stashed查看暂存区与最新提交的差异,与上面一样
  • git diff <commit1> <commit2>查看两个提交之间的差异。
  • git diff <filename>后面指定文件,只查看该文件的修改情况,没有参数查询全部
  • git diff HEAD -- readme.txt命令可以查看版本库和工作区里面最新版本的区别

git config

  • 作用:通过git config命令配置git的配置文件

  • git配置文件级别分为:

    1. 仓库级别 --local 【优先级最高】。文件所在位置仓库下的.git/config
    2. 当前用户级别 --global【优先级次之】一般配置它。文件所在位置用户家目录下的.gitconfig
    3. 系统所有用户级别 --system【优先级最低】。文件所在位置git安装目录下的 ./etc/gitconfig
  • -l--list查看配置。常用

    1. git config -l查看所有的配置信息,依次是系统级别、用户级别、仓库级别
    2. git config --local -l 查看仓库级别配置。必须要进入到具体的目录下。
    3. git config --global -l 查看当前用户配置
    4. git config --system -l 查看系统所有用户配置
    5. 可以与--show-origin 显示文件位置,--show-scope显示文件级别组合使用
  • -e--edit打开编辑器编辑指定级别的配置文件,没有指定默认仓库级别,会使用默认编辑器打开编辑。安装的时候设置的。

  • 添加配置、修改配置:直接配置对应的配置参数就行。一般配置用户级别就行。省略了--add选项。没有指定级别,默认仓库基本。常用的添加配置命令:

    1. 用户邮箱和用户名。安装git之后必设置的配置

      git config --global user.email "Your mail"

      git config --global user.name "Your name"

      如果我们没有配置,在提交代码时会有如下错误:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      
      xxx@DESKTOP-MD21325 MINGW64 /d/test/test (master)
      $ git commit -m "feature: add readme"
      Author identity unknown
      
      *** Please tell me who you are.
      
      Run
      
        git config --global user.email "you@example.com"
        git config --global user.name "Your Name"
      
      to set your account's default identity.
      Omit --global to set the identity only in this repository.
      
      fatal: unable to auto-detect email address (got 'xxx@DESKTOP-MD21325.(none)')
      
    2. 设置自己的代理。网速慢必设置的配置

      git config --global http.proxy "http://proxy_ip:port"

      git config --global https.proxy "https://proxy_ip:port"

  • --unset取消配置,注意要指定取消的配置级别。常用取消配置命令:

    1. 取消代理配置

      git config --global --unset http.proxy

      git config --global --unset https.proxy

  • --get查看指定级别、指定配置项的配置,默认仓库级别。如:

    1. 查看代理配置

      git config --global --get http.proxy

      git config --global --get https.proxy

  • git config --global alias.<alias-name> <git-command>配置⼀个git命令的快捷⽅式。例如:配置”alias.glog log –graph –oneline”使”git glog”相当于”git log –graph –oneline”.

  • git config --global core.editor <editor>配置⽂本编辑器,例如vi,在必要时⾃动打开此⽂本编辑器。安装的时候也可以指定默认编辑器。

git submodule

  • git submodule init初始化子模块,将子模块的配置信息存储在父仓库中。

    • 通常执行之后再执行更新子模块使用,如克隆带有子模块的仓库,没有加--recursive,是不会克隆子模块的
    • 初始化子模块之后,执行更新子模块就会根据配置信息下载子模块
  • git submodule update根据父仓库子模块的配置信息更新子模块,如果没有初始化子模块可以加参数--init,会下载与父项目绑定版本的子模块,若要更新加--remote

    • --init初识化子模块
    • --recursive会递归下载子模块的子模块
    • --remote根据子模块远程仓库的配置信息更新子模块,会下载最新版本的子模块
      • 注意更新之后要提交更新的版本,否则当在执行更新命令没有加--remote时会退回与父仓库绑定的版本
  • git submodule add <repository> <path>添加子模块。其中,<repository>是子模块的远程仓库地址,<path>是子模块在主项目中的路径。

    • 子模块可以当正常仓库使用。创建时<path>路径不能存在文件,更克隆差不多。

git subtree

  • 作用:将一个仓库中的目录作为另一个仓库,可以指定分支
  • 用途:搭建项目网站时,将项目网站资源推送到gh-pages分支上
    • git subtree push --prefix=dist origin gh-pages将目录添加到gh-pages分支上,dist为项目网站的目录
  • git subtree push --prefix=<prefix> <repository> <branch>将子目录的内容推送到远程仓库。它会将当前仓库中子目录的修改推送到指定的远程仓库和分支中。
    • 注意:以这种推送的方式添加的subtree不能执行subtree pull命令,只有通过subtree add添加的才能都执行,但能够执行subtree push命令
  • git subtree pull --prefix=<prefix> <repository> <branch>这个命令用于从远程仓库更新子目录的内容。它会拉取远程仓库的最新代码,并更新到当前仓库的子目录中。
  • git subtree add --prefix=<prefix> <repository> <branch>这个命令用于将远程仓库的内容作为子目录添加到当前仓库中。<prefix>是子目录的名称,<repository>是远程仓库的地址,<branch>是要合并的分支。

git rebase

  • 作用:rebase翻译成变基,顾名思义:改变基准点。可以使提交历史更加清晰和线性。

  • 原因:通过合并两个不同的分支,提交历史会很错乱。而通过变基,会使得提交历史更加整洁和可读。

  • 如何实现:就是修改创建分支的起点(基准点),到最新的提交。起点变了,提交历史就简化了。

  • 命令:

    • git rebase <base>基于<base>对当前分⽀进⾏rebase。<base>可以是commit、分⽀名称、tag或相对于HEAD的commit。
    • git rebase -i <base>以交互模式对当前分⽀做rebase。
    • rebase的过程中可能会出现冲突,解决冲突之后需要使用git add命令将解决冲突后的文件标记为已解决,然后,使用git rebase --continue命令继续rebase过程。Git会尝试继续应用剩余的提交。如果再次出现冲突,你需要重复上述解决冲突和继续rebase的步骤。
    • 如果在rebase过程中出现了问题,或者你决定放弃rebase操作,你可以使用git rebase --abort命令来撤销整个rebase操作。
  • git rebase的注意事项

    • 避免对已经推送到远程仓库的提交执行rebase操作:这可能会导致提交历史的不一致,给其他协作者带来困扰。
    • 保持工作目录干净:在执行rebase之前,确保你的工作目录中没有未提交的更改。
    • 谨慎使用:由于rebase会改变提交历史,因此在与他人共享分支时要特别小心。通常,在公共分支上应该使用merge而不是rebase。

    通过掌握git rebase的用法和注意事项,你可以更有效地管理你的Git仓库,保持代码的清晰和整洁。


扩展

.gitignore文件

Git提供了.gitignore文件,用于指定哪些文件或目录应该被Git忽略,不纳入版本控制系统中。.gitignore文件是一个文本文件,可以包含一些简单的规则,指定应该忽略哪些文件或目录。以下是一些.gitignore文件的示例规则:

  1. 忽略所有以.tmp结尾的文件:

    1
    
    *.tmp
    
  2. 忽略所有的log文件:

    1
    
    *.log
    
  3. 忽略所有的.idea目录:

    1
    
    .idea/
    
  4. 忽略所有的build目录及其内容:

    1
    
    build/
    
  5. 忽略根目录下的config.json文件,但不忽略子目录中的config.json文件:

    1
    
    /config.json
    
  6. 忽略所有的node_modules目录及其内容:

    1
    
    node_modules/
    
  7. 忽略所有的DS_Store文件(Mac OS X系统中的文件):

    1
    
    .DS_Store
    

可以将这些规则写入.gitignore文件中,并将该文件添加到Git仓库中,以使Git忽略这些文件或目录。需要注意的是,即使某些文件或目录已经被添加到Git仓库中,也可以通过修改.gitignore文件来让Git忽略它们,但需要执行以下命令才能使.gitignore文件生效:

1
2
3
4
git rm -r --cached .
git add .
git commit -m "update .gitignore"
git push

这些命令会删除Git缓存中已经添加的文件,然后重新添加文件并提交更改,以使.gitignore文件生效。

总结:

当Git执行提交操作时,它会检查.gitignore文件中列出的文件和目录,并将它们从提交中排除。这是非常有用的,因为有些文件或目录不应该被纳入版本控制系统中,例如编译生成的文件、日志文件、临时文件等。

.gitignore文件的语法是基于模式匹配的,其中的特殊字符有:

  • *:匹配任意字符,但不包括路径分隔符(/)。
  • ?:匹配任意单个字符,但不包括路径分隔符(/)。
  • /:路径分隔符,用于指定目录。
  • !:用于否定模式,即不忽略指定的文件或目录。

可以在.gitignore文件中使用通配符、路径、注释等语法,以更精确地指定需要忽略的文件或目录。同时,可以在仓库的根目录下创建一个.gitignore文件,也可以在子目录中创建独立的.gitignore文件。


git账户认证

  • 当我们对远程仓库就行修改时,需要对应的权限,不是什么人都能够修改仓库。只有通过了git账户认证,才能修改对应的仓库。
  • 常见git账户认证的方式:
    • SSH秘钥认证
      • 这是Git中最常见的认证方式之一。用户首先生成一对公钥和私钥,然后将公钥添加到Git服务器上的用户帐户中。当用户尝试与Git服务器进行通信时,Git将使用私钥进行身份验证。这种方式相对安全,因为私钥是保存在用户本地机器上的,不会被传输到Git服务器。
      • 秘钥生成命令:bash中运行ssh-keygen,一直回车就行,秘钥位置:主目录下的.ssh目录
      • 公钥设置位置:github账户Settings->SSH and GPG keys->New SSH key将公钥复制粘贴保存就行。
    • HTTPS认证
      • 在这种方式中,用户需要提供用户名密码进行身份验证。用户需要在Git服务器上创建一个用户帐户,并将其关联到本地的Git仓库中。当用户执行需要身份验证的操作时,Git会要求输入用户名和密码。这种方式相对简单,适用于个人项目或小型团队。
      • 设置位置:在使用Git进行操作时,如push或pull,系统会提示你输入用户名和密码进行身份验证。
    • 访问令牌(Personal Access Token)认证:不常用
      • 访问令牌提供了一种更安全、更灵活的身份验证方式,因为它可以限制令牌的使用权限,并且可以随时撤销或重新生成令牌。
      • 设置位置:github账户Settings->Developer Settings->Personal access tokens->Tokens (classic)->Generate new token,然后根据自己的需求设置token的权限。

ssh-keygen

ssh-keygen命令是一个用于生成、管理和转换SSH认证密钥的工具。它支持RSA和DSA两种认证密钥类型,并且提供了多种选项和参数,以满足不同的需求。

使用ssh-keygen命令,你可以生成新的密钥对,指定密钥的长度、类型以及保存的文件名。生成的私钥将保存在本地,而公钥则用于在SSH服务器上进行身份验证。

以下是一些常用的ssh-keygen命令选项:

  • -t:指定要创建的密钥类型,默认为RSA。
  • -b:指定密钥长度(以位为单位)。对于RSA密钥,最小要求是768位,默认是2048位。对于DSA密钥,长度必须是1024位(根据FIPS 1862标准规定)。
  • -f:指定用于保存密钥的文件名。如果不指定,将使用默认值id_rsa(对于私钥)和id_rsa.pub(对于公钥)。
  • -C:提供一个新注释,通常用于标识密钥的用途或所有者。
  • -P-N:分别用于提供旧密码和新密码,以保护私钥文件。如果留空,则表示不需要密码。

在生成密钥对后,你可以将公钥复制到需要访问的SSH服务器上,通常是将公钥内容追加到服务器的~/.ssh/authorized_keys文件中。这样,当你使用SSH客户端连接到服务器时,客户端将使用私钥进行身份验证,如果验证成功,你将能够无需输入密码即可登录到服务器。

请注意,私钥的安全性至关重要。私钥应该妥善保管,并且不应该与其他人共享。同时,定期更换密钥对也是保持安全性的好习惯。

除了生成和管理密钥对,ssh-keygen还提供了其他功能,如转换密钥格式、读取密钥文件等。你可以通过查看ssh-keygen的帮助文档或手册页(通过运行man ssh-keygen命令)来获取更详细的信息和用法示例。