注意:要学会使用-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的区别log项目的提交历史,reflog本地仓库的引用提交日志。- 引用会保留所以的提交历史,如何重置的历史。主要目的是提供一个安全网,以便在误操作(如错误的
git reset)后可以恢复丢失的提交或分支。 git log的输出是永久性的,而reflog会在一段时间后自动过期(默认是 30 天),以节省空间。
git rm
git rm fileName删除指定的文件。- 与
rm fileName的区别。git rm不能删除未跟踪的文件,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(重置到最新的提交)移除所有暂存区、工作区的修改,到未跟踪。这些命令其实省略了HEADgit 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、跟踪的分支等。补充如何创建远程仓库
创建远程仓库可以先在github上创建好,然后在本地pull下来,在进行修改后push上去。
可以建一个空白仓库,在本地push上去,但需要进行绑定。
1 2 3git 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 pushgit 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,分支是当前分支,这里可以省略origingit fetch origin <branch>获取特定分支的更改.
git fetch --all获取所用仓库远程仓库的最新更改。- 与
git pull的区别- 都会获取远程仓库最新的更改。
- 但是fetch不会合并,而pull会合并。可以理解为
git pull是git fetch和git merge的组合
- 获取最新更改之后可以:
git checkout <branch>检出指定分支,如果加origin要这样git checkout -b <branch> origin/<branch>git merge origin/master合并远程 master 分支的更改到当前的分支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:
- 每个分支共用一个stash。
git tag
- 作用:用于标记项目的版本发布或重要的里程碑。
- 分类
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查看
- 哈希值可以通过
git tag -a <tagname> -m "<tag message>" <commit ID>附注标签- 如
git tag -a v0.1 -m "version 0.1 released" 1094adb - 推荐id省略默认最新提交。
- 如
- 查看标签
git tag显示所有的本地tag列表,按照字母顺序排序。如果tag数量较多,可能会显示不全。省略选项-l、--listgit show <tagname>显示指定tag的详细信息,包括提交的作者、提交时间、提交信息等。git tag -n:显示tag列表,并同时显示每个tag对应的提交信息。git ls-remote --tags origin:显示远程仓库中的所有tag信息。更推荐这种。- 或者先
git fetch获取最新的更改,然后git tag检出所有标签。
- 或者先
- 删除标签
git tag -d <tagname>删除本地标签- 删除远程标签:首先需要在本地删除标签,然后推送到远程仓库
git push origin :refs/tags/<tagname>- 远程标签是
refs/tags/v0.0.1这样存在的,跟删除远程分支差不多。
- 远程标签是
- 标签一旦创建,就不能直接修改,如果需要修改标签,通常需要删除原标签,并重新创建一个新标签。
- 推送标签
- 打的标签不会自动推送到远程仓库,需要手动推送。
git push <remote> <tagname>推送指定标签到指定远程仓库,一般为origingit 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配置文件级别分为:
- 仓库级别
--local【优先级最高】。文件所在位置仓库下的.git/config - 当前用户级别
--global【优先级次之】一般配置它。文件所在位置用户家目录下的.gitconfig - 系统所有用户级别
--system【优先级最低】。文件所在位置git安装目录下的./etc/gitconfig
- 仓库级别
-l、--list查看配置。常用git config -l查看所有的配置信息,依次是系统级别、用户级别、仓库级别git config --local -l查看仓库级别配置。必须要进入到具体的目录下。git config --global -l查看当前用户配置git config --system -l查看系统所有用户配置- 可以与
--show-origin显示文件位置,--show-scope显示文件级别组合使用
-e、--edit打开编辑器编辑指定级别的配置文件,没有指定默认仓库级别,会使用默认编辑器打开编辑。安装的时候设置的。添加配置、修改配置:直接配置对应的配置参数就行。一般配置用户级别就行。省略了
--add选项。没有指定级别,默认仓库基本。常用的添加配置命令:用户邮箱和用户名。安装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 15xxx@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 "[email protected]" 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)')设置自己的代理。网速慢必设置的配置
git config --global http.proxy "http://proxy_ip:port"git config --global https.proxy "https://proxy_ip:port"
--unset取消配置,注意要指定取消的配置级别。常用取消配置命令:取消代理配置
git config --global --unset http.proxygit config --global --unset https.proxy
--get查看指定级别、指定配置项的配置,默认仓库级别。如:查看代理配置
git config --global --get http.proxygit 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文件的示例规则:
忽略所有以.tmp结尾的文件:
1*.tmp忽略所有的log文件:
1*.log忽略所有的.idea目录:
1.idea/忽略所有的build目录及其内容:
1build/忽略根目录下的config.json文件,但不忽略子目录中的config.json文件:
1/config.json忽略所有的node_modules目录及其内容:
1node_modules/忽略所有的DS_Store文件(Mac OS X系统中的文件):
1.DS_Store
可以将这些规则写入.gitignore文件中,并将该文件添加到Git仓库中,以使Git忽略这些文件或目录。需要注意的是,即使某些文件或目录已经被添加到Git仓库中,也可以通过修改.gitignore文件来让Git忽略它们,但需要执行以下命令才能使.gitignore文件生效:
| |
这些命令会删除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秘钥认证
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命令)来获取更详细的信息和用法示例。