玩转git

一.Git简介

  • 1.1 Git的特色
  1. 最优的存储能力
  2. 非凡的性能
  3. 开源
  4. 很容易作备份
  5. 支持离线操做
  6. 很容易定制工做流程
  • 1.2 web端提供git服务的产品
  1. git
  2. GitHub (全球最大的开源社区)
  3. GitLab (本身提供了CI机制,通常公司内部使用)

二.安装Git

在Git官网上有详细的安装方式 起步 - 安装 Gitcss

三.Git 配置

// 全局配置 --global
git config --global user.name 'your_name'
git config --global user.eamil 'your_eamil@domin.com'
复制代码

config的三个做用域(local、global、systemhtml

git config --local  (local只针对某个仓库有效)
git config --global (global对当前用户的全部仓库有效)
git config --system (system对系统全部登陆的用户有效,基本不用)
复制代码

显示config的配置,加--listnode

git config --list --local
git config --list --global
git config --list --system
复制代码

清除设置git

git config --unset --local user.name
git config --unset --global user.name
git config --unset --system user.name
复制代码

4、建Git仓库

两种场景github

  1. 把已有的项目代码归入Git管理
cd 进入项目所在的文件夹
git init
复制代码
  1. 新建的项目直接用Git管理
cd 进入某个文件夹
git init your_project #会在当前路径下建立和项目名同名的文件夹
cd your_project
复制代码
  1. 配置git config
git config --local user.name 'your_name'
git config --local user.eamil 'your_eamil@domin.com'
复制代码
  1. 建立readme
touch的做用是更改一个文件或目录的时间。touch readme.MD 若是readme.MD不存在,则建立空文件readme.MD
touch readme.MD 
复制代码
  1. 提交
git add readme.MD
git status 查看文件状态
git commit -m 'Add readme'
git log 查看日志
复制代码

若未add,直接commit或git status则会报以下错误(untracked files) web

config的设置中,local的设置的优先级要高于global算法

添加文件后直接commit会报错,缘由是什么?shell

五.认识工做区和暂存区

工做目录 ---> 暂存区 ---> 版本历史npm

1. git add files 将文件添加到暂存区
2. git commit 
复制代码

cp命令来拷贝文件json

clear清理屏幕

git add -u (u表明update,表明将已经被git管理的文件一块儿提交到暂存区)
复制代码

六.给文件重命名的简便方法git mv

readme文件重命名为readme.md

mv readme readme.md
git status
复制代码

发现git提示,你 deleted: readme,并新建了 read.md

以上问题的解决方法

git add readme.md 添加
git rm readme 删除
git status
复制代码

上述操做后提示,修改为功

renamed: readme -> readme.md
复制代码
git reset --hard 将刚才的修改撤回
复制代码

以上操做能够用一个更简单的命令解决

git mv readme readme.md
复制代码

这样就用git mv一个步骤解决了变动文件名

七.经过git log查看版本演变历史

git log 查看提交的完整信息
git log --oneline 只查看commit内容
git log -n4 查看最近4个
git log -n4 --oneline 组合使用
复制代码
git branch -v 查看本地有多少分支
git checkout -b testing 4323c83dcdf 基于以前的某个分支建立testing分支
复制代码
git commit -am "add testing file"  将工做区的内容直接建立到版本历史库中
git branch -av 查看有多少分支
复制代码
git log 查看当前分支的历史
git log --all 查看全部分支的历史
git log --all --graph 经过图像化的方式查看log
git log --oneline
git log --oneline --all
git log --oneline --all -n4
git log --oneline --all -n4 --graph
git log --oneline --all testing 指定的testing分支不起做用
复制代码
git help --web log 经过web查看git的全部命令
复制代码

八.用图形界面工具来查看版本历史

在命令行输入以下命令:

gitk
复制代码

不过这个图形界面的清晰度有待提升

cheery-pick就是挑选某一次的commit提交放到另外一个分支

尊重版权,显示 AuthorCommitter

九.了解.git目录

进入.git文件

cd .git
ls -al
复制代码

  • 1.查看HEAD文件
cat HEAD
显示
ref: refs/heads/RELEASE // 显示当前所在分支RELEASE
git checkout testing    // 切换分支
cat HEAD                // 再次查看HEAD文件
ref: refs/heads/testing // 显示当前所在分支为testing
复制代码
  • 2.查看config文件
cat .git/config
复制代码

显示当前项目的基础配置信息

  • 3.查看refs文件夹(引用:存放tag和tag的信息)
cd refs
ls -al
显示目录文件夹
heads // 分支 drwxr-xr-x d表明文件夹
tags  // 标签(里程碑标识)

cd heads/
显示文件夹
RELEASE
testing

cat RELEASE
acedf122defesci*******
git cat-file -t acedf122defesci*******  // 查看类型 表明RELEASE的指针指向哪个commit
commit // 显示为commit类型

git branch -av  // 查看分支进行验证

// 验证testing分支
cat testing
acedf122defesci******* // 哈希值若是足以标志惟一性则显示的较短,不然则显示的较长
复制代码
  • 4.查看objects,是git文件系统的核心内容(只要任何文件的文件相同,就是惟一的blob,这样设计的好处是什么呢?)
cd objects/
ls -al 查看详情
cd 任意文件夹
ls -al
tree 是一棵树
看树的内容用
git cat-file -p acedf122defesci*******  // 查看类型
git cat-file -p fresfer3432cxrff******* // 查看到多是css文件
复制代码

十. committreebolb三个对象之间的关系

存储是git的核心技术点,git提供优良的存储能力,对版本控制系统是很是关键的。由于版本控制系统就是管理文档,但文档的变动是很频繁的,若是没有一套好的存储机制的话,库就会愈来愈大,性能就会愈来愈差。所以设计一个良好的存储机制,对版本控制系统来讲很是关键!

  • Git对象彼此关系

(* 注:图片来自网络)

三者之间的关系

commit

一个commit对应一棵树tree(文件夹),表明取出某个commit,快照,经过树呈现出来。

tree

包含index.html readme styles,每一个文件都是一个blob,blob和文件名没有任何关系,只要内容相同,就是惟一的blob,能够大大的节约存储空间。

blob

对不一样的文件用cat命令能够进行查看

小结:

  • 1.commit中必定有一棵树
  • 2.这颗树tree里必定包含那个时间点到底包含了什么文件夹,什么文件
  • 3.这个树小有包含了各个小的树,层层展开,最后的页面节点就到了blob

十一.数一数项目中tree的个数

新建的git仓库,有且仅有一个commit,仅仅包含/doc/readme,请问内含多少个tree,多少个blob?

git init
ls-al
mkdir doc
git status // 没有变化
echo "hello,world!" > readme 建立readme并写入hello,world!
cd ../
git status
find .git/objects -type f // 空的
git add doc
git status
find .git/objects -type f // 有值,建立了blob
git commit -m "add readme"
find .git/objects -type f // 变成了4个object
git cat-file -t 083e18d   // tree
git cat-file -p 083e18d   // doc
git cat-file -t 2d832d90
git cat-file -p 2d832d90  // hello,world!
复制代码
  • 1.首先,使用git log查看提交记录。
  • 2.能够看到其中的一次提交,为"5e15bae4036c9",查看commit "5e15bae4036c9" 执行命令git cat-file -p 5e15bae4036c9

执行结果代表:该提交中包含 tree

  • 3.再次执行git cat-file -p 18baf1927939c1d88ab

执行结果代表:该提交中包含 README.md 、package.jsonblob类型的文件和 publictree类型的文件夹

从上面的例子,咱们就可总结出git中committreeblob之间的关系。

十二.分离头针状况下的注意事项

git branch -av
git log
git checkout c4ccf8ffceb142 // 输出了以下信息
复制代码

提示 You are in 'detached HEad' state.

正处于分离头指针状态。本质就是正工做在一个没有分支的状态下。 在如今的状态下有了commit,又切到了其余分支工做,这样在分离头指针状态下写的内容,极可能被git当作垃圾清理掉。因此,你想作修改变动,必定要与某个分支挂钩。

  • 在什么状态下能够用好分离头指针呢? 假如你想尝试某个功能,发现效果很差,可随时丢弃。
git commit -am"Change style" // add + commit
git checkout RELEASE // 切换以后有以下提示
复制代码

gitk --all

git branch fix_css c4ccf8ffceb142 // 根据指示信息新建分支,进行保留

git log  进行查看
复制代码
  • 分离头指针的做用:
    1. 作临时性修改的时候进行尝试
    1. 修改后的内容若是要保留,可根据提示进行操做

十三.进一步理解HEADbranch

HEAD不只能够指向某个分支,还能指向某个commit

git checkout -b fix_readme fix_css // 基于fix_css分支建立一个新的分支fix_readme,并切到新分支fix_readme

git log -n1 // (HEAD指向了新的分支)
gitk --all
cat .get/HEAD // ref: refs/heads/fix_readme

git diff 3ede435ded 490ikl9jjih  // 查看两个commit的diff
// HEAD也能够用来快速的指代
git diff HEAD HEAD~1  // 当前和父亲的比较
git diff HEAD HEAD^   // 当前和父亲的比较
git diff HEAD HEAD^^   // 当前和父亲的父亲的比较 等同于git diff HEAD HEAD~2
复制代码

十四.怎么删除不须要的分支

gitk -all
git branch -d fix_readme // 删除fix_readme分支
git branch -D fix_readme // 强制删除fix_readme分支
git branch -av // 查看剩余的分支
复制代码

不能在当前分支删除当前分支

十五.怎么修改最新commitmessage

git log -1 // 查看最近一次commit
git commit --amend // 便可修改这次commit信息
复制代码

十六.怎么修改老旧commitmessage

变基 rebase

Rebase主要有两种场景:1.合并屡次提交记录 2.合并分支

Git中整合来自不一样分支的修改主要有两种方法:mergerebase

merge合并的结果是把两个分支的最新快照以及二者最近的公共祖先进行三方合并,合并的结果是生成一个新的快照(并提交)。rebase则是另外一种方法,这种操做就叫作变基。你可使用rebase命令将提交到某一分支上的全部修改都移至另外一分支上,就好像“从新播放”同样。它的原理是首先找到这两个分支(即当前分支 experiment、变基操做的目标基底分支 master)的最近共同祖先 C2,而后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,而后将当前分支指向目标基底 C3, 最后以此将以前另存为临时文件的修改依序应用。 merge和rebase,这两种整合方法的最终结果没有任何区别,可是变基使得提交历史更加整洁。 你在查看一个通过变基的分支的历史记录时会发现,尽管实际的开发工做是并行的,但它们看上去就像是串行的同样,提交历史是一条直线没有分叉。

变基操做的实质是丢弃一些现有的提交,而后相应地新建一些内容同样但实际上不一样的提交。 若是你已经将提交推送至某个仓库,而其余人也已经从该仓库拉取提交并进行了后续工做,此时,若是你用 git rebase 命令从新整理了提交并再次推送,你的同伴所以将不得再也不次将他们手头的工做与你的提交进行整合,若是接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。

总的原则是,只对还没有推送或分享给别人的本地修改执行变基操做清理历史,从不对已推送至别处的提交执行变基操做,这样,你才能享受到两种方式带来的便利。

git rebase -i 27de432fe(要修改的父级的commit哈希)  将pick改成r 对修改后的文件进行保存。自动弹出另外一个界面。此时便可修改这次commit文案
复制代码

要修改的父级的commit哈希

r进行修改,r表明reward,只修改commit信息,出现以下信息

退出后,自动跳转到新的界面。

修改后保存退出,提示以下信息,修改为功

git log // 你会发现修改commit以后,hash值也发生了修改

git log -n5 --graph
复制代码

能够对任何一次commit进行修改

变基:基于某个基础进行变更

  • 使用rebase合并分支步骤
  1. 从master分支切出dev分支,进行开发
git:(mater)  git checkout -b feature1
复制代码

  1. 此时,你的同事完成了一次hotfix,并合并入了master分支,此时master已经领先于你的feature1分支了:

3. 此时,咱们想要把 master分支的改动同步到 feature分支,咱们经常使用的为 merge,执行:

git:(feature1)  git merge master
复制代码

合并以后的结果如上图,执行:

git:(feature1)  git log
复制代码

就会在记录里发现一些merge信息,可是咱们以为这样污染了commit记录,想要保持一份干净的 commit,此时,git rebase就排上用场了。

  1. 先回退到同事 hotfix 后合并 master 的步骤:

  1. 使用 rebase
git:(feature1)  git rebase master
复制代码

这里rebase作了什么呢?

首先,git 会把 feature1 分支里面的每一个 commit 取消掉;
其次,把上面的操做临时保存成 patch 文件,存在 .git/rebase 目录下;
而后,把 feature1 分支更新到最新的 master 分支;
最后,把上面保存的 patch 文件应用到 feature1 分支上;
复制代码

commit记录能够看出,feature1分支是基于hotfix合并后的masterfeature1便成为了最领先的分支,并且没有mergecommit记录,看起来舒服多了。

  1. rebase的过程当中,可能会出现冲突conflict。此时,git会中止rebase并会让你去解决冲突。在解决冲突后,用git add去更新这些内容。注意:add以后不要执行git commit,须要执行git rebase --continue
git rebase --continue
复制代码

这样git会继续执行余下的patch补丁文件了。

  1. 在任何状况下,咱们均可以用--abort命令参数来终止rebase的行动,而且分支会回到rebase开始前的状态。
git rebase --abort
复制代码

附:merge到一半如何取消合并

git merge --abort
复制代码

附:解决冲突git mergegit rebase中的ourstheirs

git mergegit rebase的区别:git rebase不会产生额外的commit。在实际项目中,不一样的公司倾向的使用方法不同,rebase能使commit是一条线,相对较为清晰,而merge则能完整的记录全部的操做,相对更加完整。

解决冲突:merge的时候,用git checkout --theirs留下传入的,用git checkout --ours留下当前的。 rebase的时候,用git checkout --ours留下传入的,用git checkout --theirs留下当前的。 在merge时,ours 指代的是当前分支,theirs 表明须要被合并的分支。而在 rebase 过程当中,ours 指向了修改参考分支,theirs 倒是当前分支。 mergerebase对于ourstheirs的定义是彻底相反的。

十七.把连续的多个commit整理成1个

squash

合并最近的4次提交记录:

git rebase -i HEAD~3
复制代码

这时候,会自动进入vi编辑模式:

s cacc52da add: qrcode
s f072ef48 update: indexeddb hack
s 4e84901a feat: add indexedDB floder
s 8f33126c feat: add test2.js

# Rebase 5f2452b2..8f33126c onto 5f2452b2 (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
复制代码

并提示了以下几个命令

p, pick = use commit
r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like “squash”, but discard this commit’s log message
x, exec = run command (the rest of the line) using shell
d, drop = remove commit
复制代码

将你须要合并的提交的记录前缀改成s

s cacc52da add: qrcode
s f072ef48 update: indexeddb hack
s 4e84901a feat: add indexedDB floder
p 8f33126c feat: add test2.js
复制代码

若是保存的时候,你碰到了这个错误:

error: cannot 'squash' without a previous commit // 注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。
复制代码

若是你异常退出了 vi 窗口,没关系张:

git rebase --edit-todo
复制代码

这时候会一直处在这个编辑的模式里,咱们能够回去继续编辑,修改完保存一下:

git rebase --continue  
复制代码

查看结果

git log // 两次提交合并成了一次,减小了无用的提交信息。
复制代码
git rebase -i r435dr34oi4od // 多个变动的父commit的hash复制代码

将连续的几个commit合到一个commit中

十八.把间隔的几个commit整理成一个

好比git中有两个关于readme的修改,可是是不连续的,如何将这两个commit合并为同一个?

git rebase -i 43s4dreji34fc3 // 父级commit
复制代码

将两个要合并的commit放在一块儿,使用s命令

git rebase --continue // 将commit合并

git status
 
gitk --all // 用树形结构查看,出现了两个没有祖先的commit
复制代码

将刚提交的commit撤回

git reset --soft HEAD^ // 撤回上一次的提交,并保留代码
复制代码

HEAD^的意思是上一个版本,也能够写成HEAD~1

若是你进行了2次commit,想都撤回,可使用HEAD~2

--mixed --soft --hard这几个参数的区别:

  • --mixed不删除工做空间改动代码,撤销commit,撤销git add . ,这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是同样的。
  • --soft不删除工做空间改动代码,撤销commit,不撤销git add .
  • --hard删除工做空间改动代码,撤销commit,撤销git add . ,注意完成这个操做后,就恢复到了上一次的commit状态。

commit注释写错了,能够执行下面的代码:

git commit --amend
复制代码

此时会进入默认vim编辑器,修改注释完毕后保存就OK了。

十九.怎么比较暂存区和HEAD所含文件的差别

将暂存区的文件和当前分支最近的一次commit作比较

此时已经执行过git add,文件提示已变为绿色,此时须要--cached命令来查看暂存区的diff

git diff --cached // 查看暂存区
复制代码

二十.怎么比较工做区和暂存区所含文件的差别

bare repository裸仓库,即.git下的内容

git diff -- index.html
复制代码

git diff默认比较工做区和暂存区的区别

二十一.如何让暂存区恢复成和HEAD的同样

使用情景:将文件放入到暂存区以后,在工做区又有了一次修改,感受比暂存区的要好,此时就想把暂存区的删除掉,恢复成和HEAD的同样。

git reset HEAD // 将全部的暂存区的文件取消掉,回到了工做区
git diff --cached // 验证暂存区与HEAD是否一致
复制代码

二十二.如何让工做区的文件恢复成和暂存区同样

git add index.html
git diff --cached // 暂存区
git status

// 根据提示
git checkout -- index.html
复制代码

变动工做区用git checkout ,变动暂存区用git reset.

二十三.怎样取消暂存区部分文件的更改

git reset HEAD -- index.html // 将暂存区的文件撤回到工做区
复制代码

二十四.消除最近几回提交

git branch -av
git log
git reset --hard 5def35df890d // 回到某次提交以前,以前的将会被删除
复制代码

回到你指定的commit的hash值的时候,以前的将会被删除

二十五.查看不一样提交的指定文件的差别

git log -n8 --all --graph              // 查看最近8次的提交,全部分支的状况
git diff temp master                   // 查看temp和master全部的区别
git diff temp master -- index.html     // 查看temp和master中index.html的区别
git branch -av
git diff 5df3fd1 03defx53 -- index.html // 用hash的方式查看
复制代码

此种查看方式都是查看最新的一次提交

二十六.正确删除文件的方法

rm readme             // 工做区删除
git rm readme         // 暂存区删除
git reset --hard HEAD // 恢复到了和头指针相同的状态

复制代码

其实只须要下面这一条命令便可:

git rm readme         // git rm + 具体文件,直接将删除的文件放在暂存区,就不须要在工做路径下删除文件了
复制代码

二十七.开发中临时加塞了紧急任务怎么处理

git stash             // 存放起来
git stash pop         // 释放出最新的stash
git stash list        // 查看stash信息,是否还存在
git stash apply       // 1.把以前存放的文件释放出来,2.stash中的信息还存在
git reset --hard HEAD // 使其与头指针相同
复制代码
  • popapply的区别:
    1. 执行pop以后会丢掉以前的信息
    1. 执行apply以后以前的信息还存在于堆栈之中

二十八.如何指定不须要Git管理的文件

.gitignore文件名不能修改,不然将会失效

# gitignore
HEAD
.cache
v*
alias

# For testing
test/bak
.urchin.log
.urchin_stdout
test/**/test_output

node_modules/
npm-debug.log

.DS_Store
current
/default-packages

# Only apps should have lockfiles
npm-shrinkwrap.json
package-lock.json
yarn.lock

复制代码
ls -al
vi .gitignore
rm -rf doc // 删除doc文件夹
复制代码

二十九.如何将Git仓库备份到本地

  • http/https须要用户名和密码的方式
  • ssh 须要公私钥的方式

哑协议与智能协议:

  • 直观区别: 哑协议传输进度不可见;智能协议传输可见。
  • 传输速度: 智能协议比哑协议传输速度快。

备份特色:可多点备份

git push   // 将本地的变动push到远端
git fetch  // 将远端的变动直接拉到本地

git clone --bare https://****** // 不带工做区的裸仓库

git push 远端名称
复制代码

三十.注册一个GitHub帐号

官网https://github.com/

三十一.配置公私钥

将本地和远程进行链接

在git中找到help,搜索ssh

Adding a new SSH key to your GitHub account

cd ~/.ssh
复制代码

若已经存在,须要将本地的ssh进行备份

存在一对公私钥的文件

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
复制代码

再次查看文件夹: id_rsa为私钥,id_rsa.pub为公钥。

cat id_rsa.pub // 查看公钥,以下图,须要将下面的内容粘贴到远端的github帐户
复制代码

须要将上面的内容粘贴到远端的github帐户

能够有多个 ssh key

用ssh协议的好处: push时不须要用户名和密码了,能够智能识别

三十二.在GitHub上建立我的仓库

Description:可让别人快速的搜到你的项目

Add .gitignore

Add a license MIT License开源协议

三十三.把本地仓库同步到GitHub

git remote -v

git remote add github ****** // 新增远端站点
复制代码

fetch:从远端拉最新的代码

fast-forward

git pull // 1. git fetch 2.git merge
git fetch origin ***** // 将远端分支拉到本地,还未与本地的分支产生关联
git branch -v  // 查看本地分支
git branch -va // 查看远端分支
git merge github/master // fatal: refusing to merge unrelated histories
让两个历史不想关的树merge到一块儿
git help
相同的分支非fast forward
git merge --allow-unrelated-histories github/master // 基于远端生成了一个新的commit

git push origin master
复制代码
git remote -v 查看远程版本库信息
git remote add githup <url> 添加githup远程版本库
git fetch githup 拉取远程版本库
git merge -h 查看合并帮助信息
git merge --allow-unrelated-histories githup/master 合并githup上的master分支(两分支不是父子关系,因此合并须要添加 --allow-unrelated-histories)
git push githup 推送同步到githup仓库
复制代码
在不用merge用rebase的状况下怎么操做
1)先把远端的分支 fetch到本地,而后,再执行 rebase 。
2)直接 git pull --rebase 。
复制代码

fast forward究竟是

  • 本地分支往远端分支作push,若是远端分支不是本地分支的祖先,那它俩就不是 fast forward 了。反之,它俩就是fast forward的关系。

三十四.不一样人修改了不一样的文件该如何处理

两我的修改了不一样的文件

git add -u
git commit -m ""
git push
git branch -av
git fetch // 将远端的分支拉到本地
git checkout -b feature/add_commands remotes/add_commands
git pull // note about fast-forwards 要变成fast-forwards的关系
git fetch // [ahead 1, behind 1] 远端有一个commit比本地的新
git merge // merge 远端分支
git push
复制代码

标签管理

git tag                      // 查看全部标签
git tag name                 // 建立标签
git tag -a name -m "comment" // 指定提交信息
git tag -d name              // 删除标签
git push origin name         // 标签发布
复制代码

三十五.撤销或回退已经addcommitpush的提交

命令

reset是重置的意思。多观察一下git reset这个命令。

git reset  【commit ID】
git revert 【commit ID】 // revert能够保留完整的历史记录。对于和其余人协同的项目,使用git rever是最好的。
复制代码
git reset 146bd5*****27da72  html/commons/index.html 经过hash直接将某个文件回退到
git checkout html/commons/index.html 回退以后,只是回退到了暂存区,此时还须要用checkout命令将本地的文件删除掉,再进行commit等操做,这样本地文件就与远程一致了
git push --force
复制代码

commit以后撤回:

git reset --soft HEAD^ (HEAD~1)
撤销多个commit HEAD~n // 可进行尝试

参数含义:
--mixed: 不删除工做空间改动代码,撤销commit,而且撤销git add .
--soft:  不删除工做空间改动代码,撤销commit,不撤销git add .
--hard:  删除工做空间改动代码,撤销commit,撤销git add .
复制代码

commit注释写错,改注释

git commit --amend
复制代码

持续更新...

相关文章
相关标签/搜索