Skip to content

Latest commit

 

History

History
1233 lines (727 loc) · 26.5 KB

git_command.md

File metadata and controls

1233 lines (727 loc) · 26.5 KB

git 命令

前言

git分为本地仓库和远程仓库。

git本地仓库的核心分为三部分,工作区、缓存区(或暂存区)、仓库本身,依次对应 Working Directory、index、HEAD,详情戳这里👈。

在文档中总会使用<url>这样的标记,<>中表示某种对象,整体表示的是对象值。 比如url表示的是网址,<url>表示的就是具体的那个网址,也就是那一长条的字符串。 如果英文可以直接体现含义,将不再单独解释。

推荐一个git可视化网页游戏

 

 

.git文件夹

.git/refs/heads 放置本地分支信息

.git/refs/remotes/origin 放置远程仓库origin的分支信息

.git/refs/tags 放置tags信息

.git/logs/refs/heads 放置本地各个分支commit日志信息

.git/logs/refs/remotes/origin 放置远程仓库origin的各个分支commit日志信息

.git/HEAD 记录本地当前分支

.git/objects 存储对象信息,包括数据对象、树对象、提交对象、标签对象等等。git采用无损压缩算法,将原文件内容压缩和还原,这也就是为什么切换分支后,对应的文件内容也会更新。git会将这些压缩的内容用SHA-1得到摘要,这就是object hash,摘要的前两个字符作为目录,剩下的字符作为文件名,压缩后的内容就放在这些文件里。

查看object内容的方法 git cat-file -p <object-hash>

.git/index 这个文件就是暂存区

查看该文件的方法 git ls-files

 

 

目录

 

 

本地项目推到github

  1. 在github上创建远程仓库,自动生成main分支,拷贝仓库地址 url, 拷贝authenticate token;
  2. 进入本地项目目录下执行git init, 自动生成master分支;
  3. 新建分支git branch dev;
  4. 切换到新分支git checkout dev;
  5. 提交项目所有文件到本地缓存git add --all;
  6. 把本地缓存提交到本地仓库git commit -m <message>;
  7. 添加远程仓库名称 git remote add origin <url>;
  8. 执行git push --set-upstream origin;
  9. 输入github账户名和<authenticate token>;
  10. 推送到远程仓库git push origin dev;
  11. 远程仓库将出现dev分支,包含项目中的所有代码;

 

 

返回目录 返回条目

拷取远程项目到本地

  1. 在github上拷贝仓库地址url;
  2. 进入本地存储该项目的文件夹下,执行git clone <url>;
  3. 拉取远程仓库分支的信息git fetch origin;
  4. 在本地新建一个远程仓库的同名分支develop,并和该分支关联
    git checkout develop

    也可以执行
    git checkout --track origin/develop
    还可以给本地分支换个名字
    git checkout -b mydevelop origin/develop

 

 

返回目录 返回条目

设置 git用户名、邮箱、密码

git config --global user.name <your_name>
git config --global user.email <your_email>

git config --global credential.helper store 执行后,第一次调用git pull 或者 git push,输入密码,之后就不需要输入密码了

对于github,已经改为authenticate_token验证方式,不再使用密码。

 

 

返回目录 返回条目

初始化本地仓库

假设你位于project文件夹下,且该文件夹就是你的项目根目录

此时project仅仅是文件系统的文件夹而已,并不是git本地仓库

执行 git init

结果:

  • 将project初始化为本地仓库
  • 建立一个默认分支master

 

 

返回目录 返回条目

添加远程仓库地址别名

假设你知道远程仓库地址 url
在后续 push 或者 pull 操作中,总会使用这个url
因为url本身是很长的字符串,非常不方便记忆和命令行输入
所以,类似ip地址域名的做法,给远程仓库地址取个别名使用

执行

git remote add origin <url>

origin就是别名,你可以取一个你喜欢的名字

后续使用远程仓库地址的地方,就可以使用 origin 代替

对于支持用户名和密码方式访问的git服务端,可以在url中加入用户名和 密码信息,可避免git push 或者 git pull 时再输入用户名、密码。

假设url是"https://bbhub.com/bbb.git",用户名为xiao,密码为ak47,
则加入用户名和密码的url为"https://xiao:[email protected]/bbb.git".

最后执行git remote add origin <url>即可
后续执行和origin相关的push和pull操作,就不会再用输入用户名、密码

 

 

返回目录 返回条目

修改远程仓库地址别名

假设当前远程仓库地址别名是 origin,但出于某种原因,必须要改为 own

执行

git remote rename origin own

很好理解,把某个名字重命名为另一个名字,旧名字当然在前,新名字在后啦

 

 

返回目录 返回条目

修改别名对应的远程仓库地址

假设当前仓库地址别名是 origin, 但是远程仓库地址由<url> 改成了 <new_url>

考虑到兼容性,你想继续使用 origin作为远程仓库新地址的别名

执行

git remote set-url origin <new_url>

 

 

返回目录 返回条目

查看别名对应的远程仓库地址

假设当前仓库地址别名是 origin,但你想不起来origin对应的远程仓库地址是什么了

执行

git remote get-url origin

 

 

返回目录 返回条目

查看远程仓库别名及其地址的列表

git remote -v

 

 

返回目录 返回条目

拷贝远程仓库

git clone <url>

url是远程仓库地址.

假设远程仓库的默认分支是main,在上述指令执行完毕后

  • 你将拥有一个本地仓库
  • 本地仓库会有一个main本地分支, 该分支会与远程main分支关联
  • 你将得到一个自动创建的远程仓库的别名origin
  • 你将获取远程仓库所有分支的分支信息,用git branch -r可查看

如果你想更进一步,在拷贝完远程仓库后,不留在main分支,而是新建 一个和远程分支同名且关联的本地分支,然后留在这个新的本地分支

可执行 git clone -b <branch-name> <url>

分支名一定要和远程仓库众多分支中的一个保持一致!

 

 

返回目录 返回条目

新建本地分支

git branch <branch-name>

将从当前分支拉出一个新分支,名字为<branch-name>

你也可以基于tag创建分支:git branch <branch-name> <tag-name>

 

 

返回目录 返回条目

切换本地分支

假设你处于分支master,想切换到分支dev

执行 git checkout dev

 

 

返回目录 返回条目

新建本地分支并切换到这个分支

假设你处于分支master,想创建一个新分支dev,并切换到dev分支

执行 git checkout -b dev

 

 

返回目录 返回条目

新建关联远程分支的本地分支

假设你处于分支dev, 并知道远程仓库的一个分支名dev_remote_1

你发现本地没有一个分支关联这个远程分支

你想创建一个新的本地分支关联这个远程分支

  • 执行 git checkout --track origin/dev_remote_1

    在本地创建一个dev_remote_1分支,并切换到该分支,且 该分支和远程的dev_remote_1分支关联

等效于 git branch -t dev_remote_1 origin/dev_remote_1 git checkout dev_remote_1

  • 执行 git checkout dev_remote_1

    效果同上, 但本地不能有叫做 dev_remote_1的分支,否则 会直接切换到该分支,不会创建新分支

  • 执行 git checkout -b dev_1 origin/dev_remote_1

    本地创建一个叫 dev_1的分支,该分支与远程分支dev_remote_1 关联,并切换到dev_1分支

如果上述执行失败,请执行 git fetch origin -a, 再重试

 

 

返回目录 返回条目

删除本地分支

git branch -d <branch-name>

分支<branch-name>必须和远程分支完成充分的合并,或者根本 没有关联到远程分支。

或者

git branch -D <branch-name>

强制删除。

 

 

返回目录 返回条目

删除远程分支

假设你位于 dev 分支,要删除的是远程 dev33分支。

方法一:
git push origin : <remote-branch-name>

git push origin :dev33
会删除remotes/origin/dev33 分支记录,还会删除远程仓库origin的dev33分支;

方法二: git push -d origin <remote-branch-name>

git push -d origin dev33

注意
git branch -d -r origin/dev33

只会删除remotes/origin/dev33 分支记录,不会影响到远程分支; 本地分支也可以命名origin/dev33,所以用 -r 表示后边的分支指代远程仓库分支记录, 是remotes/origin/dev33分支记录; 如果省略 -r ,只会删除本地名为origin/dev33的分支。

如果在bash中:

$ git branch -a 
* master
  remotes/origin/master

remotes/origin/master 是远程仓库origin的master分支,在本地仓库的一个记录;

 

 

返回目录 返回条目

重命名本地分支

git branch -m <old-branch-name> <new-branch-name>

很好理解,把某个分支移动为另一个分支,因此旧的分支名在前, 新的分支名在后

 

 

返回目录 返回条目

查看本地分支名单

git branch

 

 

返回目录 返回条目

查看远程分支名单

git branch -r

r 就是 remote

 

 

返回目录 返回条目

查看所有分支名单

git branch -a

a 就是 all

 

 

返回目录 返回条目

查看本地分支详细信息

git branch -vv

可获取 本地分支名、本地分支关联的远程分支名、本地分支版本是否领先远程分支;

For example:

      iss53     7e424c3    [origin/iss53: ahead 2] forgot the brackets
     master     1ae2a45    [origin/master] deploying index fix
 *serverfix     f8674d9    [teamone/server-fix-good: ahead 3,
                            behind 1] this should do it
    testing     5ea463a    trying something new

head 2 表示本地分支有2个提交没有同步到远程分支
behind 1 表示远程分支有1个提交还没有合并到本地分支
*号表示当前分支

 

 

返回目录 返回条目

将本地分支和远程分支关联

假设:

  • 你处于分支dev
  • 远程仓库名你已经设定为origin
  • 你想将分支dev和远程分支develop关联

执行 git branch -u origin/develop

-u 是 --set-upstream-to 的缩写

设置关联的好处:
当你想push或者pull的时候,只需执行git push origingit pull origin, 关于远程分支的信息可省略

 

 

返回目录 返回条目

取消本地分支和远程分支的关联

假设你处于分支dev,该分支已经和远程分支develop关联,你想取消关联

执行 git branch --unset-upstream

 

 

返回目录 返回条目

拉取远程分支的分支信息到本地

  • 执行

    git fetch origin dev

    拉取远程分支dev的分支信息到本地,执行 git branch -a 将会看见remotes/origin/dev

  • 执行 git fetch origin -a

    拉取远程仓库origin所有分支的分支信息到本地

 

 

返回目录 返回条目

添加文件到本地仓库的缓存区

项目中的文件在最开始只是停留在文件系统中,git没有对它进行版本跟踪

需要将文件添加到本地仓库缓存区后,git才会对它进行版本跟踪

执行 git add <文件存储路径>

第一次执行时,文件会被git跟踪
之后执行时,文件的改动信息会被存储到本地仓库缓存区

对于所有已被追踪的文件,可以一步到位 git add --all

 

 

返回目录 返回条目

撤销git add

你执行完 git add指令,将一些文件的修改加入到本地仓库的缓存区后,觉得
不妥,想撤销刚才的 git add操作,

执行
git reset HEAD <filename>

指定的文件就会被取消已发生的 git add操作

 

 

返回目录 返回条目

把缓存区的信息提交到本地仓库

git commit -m <message>

message 是本次提交的一些说明,方便以后查看提交记录排查问题、锁定重要版本代码

还有另一种情况极为常见

  • 你执行了一次git commit操作
  • 之后,你发现提交的message有问题,或者代码修改仍存在问题

你很可能按照 git add、git commit的流程再来一遍,这样你会提交了 两次,但是你也可以只提交一次

你要做的就是

  • 继续修改文件,改完后 git add
  • 提交的时候执行 git commit --amend

这样,你不会重新提交一次,而是将上一次和本次的提交合并为一个来处理

 

 

返回目录 返回条目

文件恢复到上次commit时的样子

在开发过程中,固然可以借助编辑器的撤销指令回退,但你无法确定回退到哪一步 刚好是上次提交后的情形。如果你想将文件的内容恢复到上次提交后的样子,执行 git checkout -- <filename>

注意,这将改变本地文件系统中的文件,而文件在本地仓库缓存区中的记录不会受到 影响

 

 

返回目录 返回条目

取消git对文件的版本追踪

git rm --cached <filename>

文件将会从本地仓库的缓存区中移除,不再接收git的版本追踪,但不会从文件系统中删除

如果想更进一步,把文件也删除掉,执行 git rm <filename>

 

 

返回目录 返回条目

重命名文件并更新到缓存区

当你修改文件名称后,缓存区的信息将和文件不一致,此时你还要重新git add, 当然,有一种更简单的方法,执行
git mv <filename> <file_newname>

 

 

返回目录 返回条目

比较缓存区和工作区的差异

git diff

返回本分支文件在缓存区和工作区的差异

你修改一个文件,执行git add,之后你继续修改这个文件,你在某个 时间点想知道手头上的文件,和上次git add时有什么差异,就可以用此命令

 

 

返回目录 返回条目

比较缓存区和本地仓库中文件的差异

git diff --cached

你使用git commit 完成了一次提交,此时所有文件的状态记作A, 你又开始工作,修改了一些文件,之后执行git add将改动加入缓存 区,此时缓存区中所有文件的状态记作B,这时你想看看A和B之间有什么 差异,就可以用该命令

 

 

返回目录 返回条目

比较本地两个分支本地仓库中的差异

git diff <branchname1> <branchname2>

 

 

返回目录 返回条目

比较本地两个分支本地仓库某文件的差异

git diff <branchname1> <branchname2> <filename>

 

 

返回目录 返回条目

查看本地两个分支有哪些文件存在差异

git diff <branchname1> <branchname2> --stat

 

 

返回目录 返回条目

本地分支推送到远程仓库

在完成了 git commit后,就可以将本地分支推送到远程仓库

假设你位于本地分支main, 并准备推送到远程分支develop

git push origin main:develop

  • git push 默认会选择推送给origin
  • 把某个分支推送到另一个分支,本地分支名当然在前,远程分支名当然在后啦
  • 如果省略:develop,会将main分支推送到它所关联的远程分支, 没有关联的远程分支的话,就会在远程仓库创建一个新的同名分支,并推给这个分支。本地会生成 origin/main虚拟分支。
  • 如果省略main,相当于删除远程分支develop
  • 如果本地分支已经关联到远程分支develop且二者同名,
    可简写为git push origin
    • 尽管本地分支和远程分支关联, 但他们的分支名字不同,git会考虑安全问题选择拒绝执行push。

 

 

返回目录 返回条目

远程分支和本地分支合并

当远程分支有更新,你需要让本地分支与远程分支同步一下

假设你位于本地分支main,要去同步的远程分支为develop

git pull origin develop:main

  • 把某个分支拉到另一个分支上合并,远程分支名当然在前,本地分支名当然在后啦
  • 如果省略:main,会将远程分支develop拉取到当前本地分支
  • 如果当前本地分支已经关联远程分支develop且二者同名,可简写为
    git pull origin

如果想让两个本地分支合并,可以使用git merge 命令:

  1. git merge jack 将jack分支合并到当前分支
  2. git cherry-pick <commit-id> 将某次提交所做的改动合并到当前分支上,也可以是多次提交,提交ID号用空格隔开即可。

 

 

返回目录 返回条目

设置本地分支默认推送到哪个远程分支

假设你位于本地分支main,想让该分支每次git push操作推送给远程分支develop

git push --set-upstream origin develop

对于git pull的情形,同理有
git pull --set-upstream origin develop

设置本地分支和远程分支相关联,其实就是同时完成了上边的两个设置

 

 

返回目录 返回条目

打标签

  • 执行git tag <tagname>, 会根据当前本地分支上一次的git commit结果创建一个标签

    或者,更进一步,你可以为标签添加一些解释信息
    git tag -a <tagname> -m <message>

    你也可以根据某一次的commitID创建标签
    git tag <tagname> <commitID>

    实际上git tag <tagname>git tag <tagname> HEAD的缩写

  • 推送到远程仓库
    git push origin <tagname> 或者 git push --tags origin

在github上的tags列表就能看到你新创建的标签

 

 

返回目录 返回条目

查看本地仓库都创建了哪些标签

git tag -l or git tag

 

 

返回目录 返回条目

查看远程仓库都有哪些标签

git ls-remote --tags origin

返回目录 返回条目

删除本地分支的标签

git tag -d <tagname>

 

 

返回目录 返回条目

删除远程仓库的标签

git push origin --delete <tagname>

 

 

返回目录 返回条目

基于标签创建一个本地分支

git checkout -b <branchname> <tagname>

你开发完v1.0.0的代码,打好一个标签v1.0.0

你要接着v1.0.0的代码开发v2.0.0的代码

你就可以使用上述指令创建一个新的分支,在该分支上继续你的开发

 

 

返回目录 返回条目

查看本地分支提交历史

git log

你可以从输出看到每一次提交信息,最重要的是commitID;

该指令还有一些拓展用法

  • git log -2 只显示最近两次的提交记录

  • git log --since=2.weeks 只显示最近两周内的提交记录

  • git log --util=2.weeks 只显示两周之前的提交记录

  • git log --author=jack 只显示提交记录中作者是jack的所有记录

  • git log --committer=jack 只显示提交记录中提交者是jack的所有记录

  • git log --grep=mm 只显示提交记录message中包含 mm的所有记录

  • git log -S straw 只显示添加或者删除内容匹配straw的提交记录

  • git log --stat 额外列出修改的文件名

  • git log --shortstat 额外显示--stat中修改的行数信息

  • git log -p 额外列出被修改的文件,改前和改后的差异

  • git log --pretty=oneline 每一个提交的记录单行输出,除了oneline还可以有 full short fuller format

  • git log --pretty=format:"%h %an %ar %s"
    采用format,自定义输出信息格式
    %h 提交的简写hash码
    %H 提交的完整hash码
    %an 作者名字
    %ae 作者邮箱
    %ad 作者修订的日期
    %ar 作者多久前修订的
    %cn 提交者名字
    %ce 提交者邮箱
    %cd 提交者修订的日期
    %cr 提交者多久前修订的
    %s 提交的信息

 

 

返回目录 返回条目

本地分支回滚到某一个版本

使用git log找到某一版本的commitID

  • 执行
    git reset <commitID>

    缓存区和本地仓库数据会回滚到该版本,工作区不受影响

  • 执行
    git reset --sort <commitID>

    本地仓库数据会回滚到该版本,工作区和缓存区不受影响

  • 执行
    git reset --hard <commitID>

    本地仓库、缓存区、工作区数据回滚到该版本

在此基础上,执行一步git push操作即可完成远程分支版本回滚

 

 

返回目录 返回条目

状态暂存并切换分支

假设你在dev_1分支上编写代码,出于某种原因,你要切换到dev_2分支
修改一些代码,可是,你没有git add和git commit,无法完成分支切换,
这种情况下,你可以

  1. git stash
  2. git checkout dev_2
  3. 解决dev_2的代码问题,在commit后,切换回dev_1分支
  4. git stash apply or git stash pop
  5. 继续修改dev_1分支上未完成的编码工作

 

 

返回目录 返回条目

终端无法正常显示中文字符

当你执行 git status 后,如果发现终端无法显示正常的中文字符,你可以 这样解决:
执行 git config --global core.quotepath false

 

 

返回目录 返回条目

大文件拒绝push

当你要提交的文件中,出现单文件超过100MB的文件时,会被github远程拒绝,而你尝试删除该文件后,发现依旧会被拒绝,这是因为在过去的commit记录中,保留该文件的信息。

为了解决这个问题,你需要:

brew install git-filter-repo

# PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA要替换成大文件的路径,注意是路径,不能只包含文件名哦
# 如果运行不成功,需要增加 --force
git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA

# 运行成功后,远程仓库的地址可能会被删除,重新加入一下即可

 

 

返回目录 返回条目