正式开始
git init
相当于将工作区文件修改提交到暂存区
git add <filename>
git add . // 添加当前目录下所有被改变的的文件
将暂存区的文件修改提交到本地版本库
git commit -m "message"
注意 -m 后面的message 必须用双引号,
追加提交
git commit -m " this is test amend commit"
git add < filename>
git commit --amend // 此命令会打开编辑窗口,用于编辑前一次的commit message。
上面的三个命令只会产生一个提交记录
// 工作区
git diff 工作区暂存区的区别
git diff 指定版本和工作区的区别。
// 暂存区
git diff --cached 工作区和版本库最新版本的区别
git diff --cached 指定版本和暂存区的区别。
// 版本之间
git diff 查看两个版本之间的区别
git status
这个命令可以用来查看哪些文件在工作区有修改,哪些修改已经提交到了暂存区。git diff
则是查看文件具体的修改
git log // 全量展示
git log --pretty=oneline // 将每条记录选取关键信息合成一行展示。
git log --abbrev-commit // 将commit id 显示为缩写。
git log --graph // ASCII图展示每次的提交所在分支以及分支分化衍合情况
git log -5 // 展示最近的五条数据提交记录
git log --author <authorName> // 按作者名过滤
git log --grep <commit message> // 按提交信息
git log -- <fileName> // 按文件名
以上的这参数可以组合使用
推荐使用如下配置
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
执行上面的命令之后,就可以直接git lg
就可以显示格式化好之后的日志了。
git reflog 查看所有版本操作相关的,例如版本回退等等的记录,也就是HEAD指针指向的位置的历史记录,即ref的log,即对版本库中的代码的增删改查记录。
reflog 是存储于本地的日志并不会共享。
在git 中HEAD表示当前的版本,HEAD^ 表示上一个版本,HEAD^^ 表示上上个版本。较多的试试直接用数字指定。例如:HEAD~10。
注意:^ 字符是windows的cmd.exe 中的元字符。windows下使用HEAD^可能会报错
fatal: ambiguous argument 'HEAD
': unknown revision or path not in the working tree.
这时要使用HEAD"^ “或者"HEAD^”,来避免它。
例如
git reset --hard HEAD^ 强制回退上一版本
git reset --hard HEAD~1
git reset --hard < commit id> 默认为HEAD
以下操作慎用,命令使用之后不一定能够有反悔的机会。因为只有在对版本库中的文件进行增删改查的时候,在git log或者git reflog中才会有日志记录。尤其在使用–hard 的时候更有可能会直接无提示的清空掉工作区和暂存区的数据
从工作区撤销修改
将该文件在工作区的修改全部撤销,相当于将工作区的文件修改为和暂存区的一致。
git checkout -- < filename>
filename 是必填的
从暂存区撤销修改
如果文件已经提交到了暂存区,首先需要撤销暂存区的修改,
git reset HEAD < filename>
将暂存区的修改回退到工作区,然后根据需要决定是否撤销工作区的修改,如果需要继续撤销,参考上一条。
从本地版本库撤销修改
git reset <options> <commit id>
// 回退 options 默认为mixed commit id默认为HEAD
git reset --mixed 保留工作区,把暂存区的改变回退到工作区,移动HEAD指针,暂存区和HEAD指针的版本一致。
git reset --soft 保留工作区和暂存区,仅移动HEAD指针,所有的reset都会执行这个操作。
git reset --hard 清空工作区和暂存区的改变。移动HEAD指针,暂存区与工作区和HEAD指针的版本一致。
git reset --merge 如果暂存区为空,此命令无效果。如果工作区和暂存区存在对同一文件的修改则会失败。一个文件工作区无修改,暂存区存在修改的时候生效,即工作区和暂存区相同但是还没有提交到版本库。此命令会清空工作区和暂存区。移动HEAD指针。这类文件的暂存区和工作区同步为HEAD指针的版本一致。
git reset --keep 保留工作区,把暂存区的改变也回退到工作区,移动HEAD指针,暂存区和HEAD指针的版本一致。
–mixed 和 --keep的区别在于,恢复到历史版本的时候,如果工作区或者暂存区存在修改的文件在要恢复历史版本和HEAD指向的版本之间存在不同,mixed会直接恢复,–keep会失败。
撤销远程库修改
先撤销本地的修改,然后推送到远程库即可。
git push -f // 强制推送到远程库 慎用---可能会被打
只恢复指定版本的内容其他版本不变。可以使用revert(反做)命令。
git revert <commit ID>
revert 命令用于反做某一次的提交,然后形成一条新的提交记录。
只恢复指定的文件其他文件不变
恢复之后需要手动提交,才会保存到版本库。
git checkout <commit id> fileName
git reset、git revert、git checkout
git reset 指的是恢复到某一个版本。这个版本之后的commit都会被放弃。
git revert 指得的是恢复某一个版本的修改。不影响其它的commit。反做这个版本的更改,并形成一条新的commit
git checkout 是指恢复某一个文件,并不移动HEAD指针,相当于只是读取某个文件的历史版本覆盖到工作区和缓存区。
注意: 工作区和暂存区被清空的时候可能会没有提示 慎用
git rm < filename>
删除文件之后提交即可。
添加远程库并将远程库命名为 origin ,命名可以自定义。但是一般都是origin吧。
git remote add origin [email protected]:************.git // 添加远程库
删除本地添加的名为 origin的远程库
git remote rm origin
将master 中的修改推送到远程库
git push -u origin master
git push origin :master // 只推送指定的commit
-u 表示把本地的master 分支和远程的master关联起来,第一次推送的时候使用,之后就可以只使用git push 命令进行推送了。
git push -u origin master
这个命令会自动把 远程库origin中的master分支和本地的master分支关联起来,然后推送。
git push -u origin webpack
这个命令会把 远程库origin中的webpack分支和本地的webpack分支关联起来,如果远程库没有webpack分支,会自动创建webpack分支,然后再推送代码。
git push -f origin master
用本地库的master分支强制覆盖远程库origin中的master分支,这个一般应该用不着,用了可能会挨打。
如果想要 实现,比如本地的webpack分支关联远程的master分支,可以通过git branch --set-upstream-to=origin/master webpack
把两个分支关联起来。然后自行推送,推送的时候远程库分支和本地库分支名字不相同的时候,推送比较麻烦点,git好像会警告。
git branch --unset-upstream
用于解除两个分支之间的关联关系。
git branch -vv
查看本地各个分支关联的是哪个远程分支
将远程库拉取到本地
git pull
// 下面是拉取到本地后强制覆盖掉本地的修改
git fetch // 相当于拉取到本地存储的远程库的副本中
git rebase // 从本地的远程库副本中恢复到本地库。
git reset --hard origin/master // 从远程库副本中强制恢复,覆盖本地库
git clone [email protected]:******.git ## 默认克隆master 分支
git clone -b < branchName> [email protected]:******.git 克隆指定的分支
git clone 之后
使用git branch -r 查看远程仓库所有的分支,
git checkout < remote branchName> 便可以获取指定的远程仓库的分支了。
git remote
git remote -v 查看远程库信息的信息
F:\git\gitskills>git remote -v
origin [email protected]:****.git (fetch) 拉取分支地址
origin [email protected]:****.git (push) 推送分支地址
创建dev分支并切换到dev分支。
git checkout -b dev
相当于下面的两个命令的集合。
git branch dev 创建dev分支
git checkout dev 切换到dev
从指定commitId或tag创建分支
git checkout -b <newBranchName> <commitID/tagName>
例如:
git checkout -b webpack abcdef
// 会从 abcdef 这个commitID创建一个名为webpack 的分支
checkout 命令前面用来撤销修改,这里用来操作分支,这一个命令干了很多事,不太好。所以新版的git(文档是2.27添加的)添加了一个新的命令switch
用来操作分支,更清晰。
* 实验性功能
git switch <branchName> // 切换到该分支
git switch -c <newBranchName> // 创建并切换到该分支 -c 是 --create的缩写 如果分支已存在则会失败
git switch -C <branchName> // 创建并切换到该分支,如果该分支已存在则重置该分支 --force-create 的缩写 git branch -f 命令类似
git switch (-c|-C) <branchname> <<start-point> // 从指定提交创建分支
git switch --orphan <new-branch> // 创建一个没有文件的任何空白分支,不知道有啥用 ,,,,
重命名当前分支
git branch -m <new Name>
git branch 查看本地的分支信息
git branch --remote 查看远程的分支信息 简写 git branch -r
git branch --all 查看所有的分支信息本地+远程 简写:-a
git merge dev // 将dev 分支合并到当前分支,无冲突的时候,fast-forward模式。
git merge --no-ff -m "" dev // 将dev 分支合并到当前分支,使用普通模式。不使用fast-forward模式。如果没有-m参数会自动生成一条commit message。
git cherry-pick hash-code 合并指定的提交记录
普通模式合并可以从log中看到做过合并,fast-forward看不出做过合并。
git fetch
获取远程所有分支,使用git branch -r
查看远程分支,例如origin/testRemote,执行git checkout testRemote
,会新建一个与远程分支同名的本地分支,并自动与该远程分支关联。所谓解决冲突就是将冲突的文件,编辑为我们需要的内容然后提交。
删除dev分支
git branch -d dev
存在没有合并内容的分支,会提示不允许删除,如果确定需要强制删除该分支,使用。
git branch -D dev
把该分支上的修改提交到远程库 即将本地master分支 推送到origin的master分支
git push origin master
关于分支
master 分支需要时刻和远程的一致
dev 分支也需要和远程的一致
bug 分支一般不需要
feature 分支取决于是否有人合作,(新功能分支)
git branch --set-upstream-to=origin/dev dev
将远程的dev 分支和本地的dev分支连接起来
我们使用git clone *** 远程仓库的时候默认只会克隆master分支。
如果我们在本地创建了dev 分支之后,想要向远程库的dev分支提交数据,需要使用这个命令将两个仓库关联起来然后才可以提交代码。
为了不和暂存区的理解混淆,我把它直译为贮藏(或者“储藏”也可以)。
贮藏工作状态即存储下工作区和暂存区的状态。
git stash
// 贮藏并添加说明
git stash save ""
查看贮藏列表
git stash list
查看某一个贮藏记录中的工作状态和当前工作状态的区别
git stash show stash@{
0}
// 查看更具体不同的内容
git stash show stash@{
0} -p
git stash apply // 从stash记录中恢复工作区并不删除stash记录
git stash pop // 恢复工作区的同时删除记录
git stash apply stash@{
0} 恢复到指定的记录
git stash apply/pop --index 恢复工作区的同时恢复暂存区
git stash drop // 删除stash的记录 默认最新,可以指定
git stash clear 清空列表
git stash branch
rebase 命令,有以下三个功能。
我们在本地针对同一个文件进行了多次提交,如果直接推送到远程库,提交的之后,查看远程库中commit记录会非常的多。我们可以将这多条的commit 记录合并为一条记录。
例如。我对有三条已经提交的记录。进行合并
F:\test\gitskills>git log --pretty=oneline --abbrev-commit -5
a1728f3 (HEAD -> dev) this is thired 333333
a10dea5 this is second 222
572c1e7 this is first
1a9c5cf merge test // 这是基础版本
9031e2d (test-me) test m e branch
git rebase -i HEAD~3 // 合并最近三次的提交
会有如下输出。中文翻译是我自己写的。
pick 572c1e7 this is first
pick a10dea5 this is second 222
pick a1728f3 this is thired 333333
# Rebase 1a9c5cf..a1728f3 onto 1a9c5cf (3 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
# 使用这一次提交,把它融入到前一次提交中,但是抛弃提交记录中的log message
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop = remove commit
# l, label
# t, reset
# m, merge [-C | -c ]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c to reword the commit message.
#
将前三行修改为
p 572c1e7 this is first
s a10dea5 this is second 222
s a1728f3 this is thired 333333
保存文件后,会自动弹出下面的内容,因为我们选取的是第一条记录将其他两条记录合并进来,我们修改下第一行记录的commit message。之所以修改第一样是因为在一行展示log的时候,会看不到换行之后的message。但是实际上message 是合并了的。多行查看log的时候会看到。
p 572c1e7 this is first
# This is a combination of 3 commits.
# This is the 1st commit message:
this is first !!!修改这里的message
# This is the commit message #2:
this is second 222
# This is the commit message #3:
this is thired 333333
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sat Jul 27 18:55:57 2019 +0800
#
# interactive rebase in progress; onto 1a9c5cf
# Last commands done (3 commands done):
# squash a10dea5 this is second 222
# squash a1728f3 this is thired 333333
保存成功之后,在查看提交记录。可以看到三条合并记录被合并成了一条。commit message 也会合并。
F:\test\gitskills>git log --pretty=oneline --abbrev-commit -3
27c3c39 (HEAD -> dev) this is first message for rebase
1a9c5cf merge test // 这个是基础版本
9031e2d (test-me) test m e branch
☺我是不会说的,自己理解吧。
git rebase 合并分支之后。提交记录里面不会有分支合并的记录。
例如A、B、C 三个分支。B,C分支是均从A切出。然后在B分支上进行了commit操作,然后将它合并到了A分支。这个时候A分支就会比C分支的快上一个commit。此时如果我们需要把C分支的commit合并到A分支的话,首先要在C分支把A分支比C分支快的一个commit合并过来,然后再将C分支合并到A分支。
将A分支比C分支快的一个commit合并过来这个操作, 有两种方法进行:
git merge / (git pull 针对远程分支)
如果有冲突,处理冲突然后执行git add --> git commit -m “”.
处理完成后的日志记录。
F:\test\gitskills>git log --pretty=oneline --graph --abbrev-commit -5
* cd87169 (HEAD -> testRebase) Merge branch 'dev' into testRebase // 产生的新的commit记录
|\
| * 8d7c328 in dev for test rebase
* | bd601fe commit in testRebase
|/
* 27c3c39 this is first message for rebase // 这个是切分支的时候的基础版本。
使用git rebase合并
git rebase dev
// 如果两个分支之间创建了链接则可以直接执行 git rebase
如果需要处理冲突,处理冲突后执行 git add < conflictFileName> --然后执行-> git rebase --continue,即可继续完成rebase。
处理完成后的日志记录。和前面的一种方法相比干净了些,不会产生新的提交记录。
F:\test\gitskills>git log --pretty=oneline --graph --abbrev-commit -5
2263f26 (HEAD -> testRebase) commit in testRebase
8d7c328 (dev) in dev for test rebase
27c3c39 this is first message for rebase // 这个是切分支的时候的基础版本
标签相当于给某个commit id创建了一个别名
git tag V1.0 默认是当前的HEAD
git tag v1.9 < commit ID> 给指定commit 创建别名
git tag 查看所有的tag tag 是按照字母排序的。
git tag -a < tagName> -m "" 创建tag 并添加说明
git show < tagName> 查看该tag 的详细信息
git tag -d < tagName> 删除标签
git push origin < tagName> 推送指定的标签到远程库
git push origin --tags 推送所有的标签到远程库
删除远程库的tag
首先删除本地的tag
git tag -d < tagName>
然后删除远程库
git push origin :refs/tags/< tagName>
使用 .gitignore文件,要忽略的文件名或者文件夹,一个一样的添加进去就可以了,可以使用正则。
// 禁止 git 自动将LF转换为CRLF
git config --global core.autocrlf false
使用配置给git命令添加缩写
git config --global alias.st status
// 有用的快捷键
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
–global 全局配置,不加的话只对当前库生效
查看配置
git config --global -l
误操作的时候试试 git XXX --abort
可能有救。
git 执行一些命令的时候出现如下错误
error: Your local changes to the following files would be overwritten by merge:
// 下面的内容有的命令有,有的没有,但是并不影响,
Please commit your changes or stash them before you merge.
错误原因:你当前执行的命令会覆盖掉工作区或者缓存区的未提交到版本库的修改,导致工作区缓存区的修改丢失,所以git拒绝了你的操作。
解决方法:
使用stash存储下当前的工作区和缓存区,执行完要执行的命令后,再从stash恢复。
提交当前的工作区和缓存区的内容到本地版本库,然后再执行命令。
放弃工作区和缓存区的修改,
放弃工作区和缓存区的修改,由于还没有提交到版本库是不会有记录的,恢复可能不大, 慎用!!!
方法有:
3.1. git reset 具体使用查看下这个命令的介绍。
3.2. 执行命令的时候试试 --hard 或者 -f 参数。
warning: LF will be replaced by CRLF in xxxxxxxxxx
警告原因:本地的文件使用的是LF 作为换行符,windows(其它不晓得)下git的默认配置会有一个 autocrlf,即自动把LF转换为CRLF。
影响:如果有的人本地是LF有的人是CRLF,有的人自动转换有人不转换。最终有的人提交的时候会发现几乎所有的文件都有修改提示,而实际上只是换行符发生了变化而已。
解决方法:修改配置,建议,对同一个库提交代码的所有人应该统一配置。提交的时候使用统一的换行符号。
git config –global core.autocrlf false // 关闭自动转换为crlf
f:\test\liu\gitskills>git reset HEAD^
More?
More?
fatal: ambiguous argument 'HEAD
': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git [...] -- [...]'
原因:^ 是windows下cmd.exe的元字符,导致windows对命令的解析出现了问题。
解决方法:
执行命令的时候 使用HEAD"^"、"HEAD^ "、HEAD~、commit id等等。
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> master
fatal: branch 'master' does not exist
git checkout master
我是在添加子模块的时候出现的,处理方法是:
删除与.git / modules /目录下的子模块具有相同路径的文件夹。当添加子模块时,如果子模块的url不正确,则会出现此错误。
fatal : 致命的
之前总是理解不了pull request,因为这个操作明明是把代码推送到别人仓库,不应该是push request么,后来有人把它翻译为 ‘求拉’,即请求对方拉取我的代码。是站在对方的角度的。
要是还是没学会?总是记不住命令什么的。试试Github Desktop吧!!
TortoiseGit.org 也不错