Git笔记-命令集合
所有的版本工具,包括Git都只能对文本文件进行版本控制,若是改动图片、视频等(图片内容修改或视频剪辑),Git只会知道其大小变了,但不知道具体修改了什么,所有都不能进行版本控制。
git add filename
将名字为filename的文件添加到一个暂存空间
之所以需要这一步是因为,git可以一次add多个文件到一个暂存空间,然后一起commit(下一个命令,提交更改)。我的理解是,如果每个文件更改都是commit到git,这样会产生大的开销。
git commit -m “log”
将上次commit之后add到仓库的文件提交到git。
-m “log”:-m是message到缩写,后面跟的是对这次提交的说明。log最好是有实际意义的,因为这样会方便同伴和自己检查更新。
git status
git status用于查看工作区的状态,即.git所在目录是否有文件变动。
可以分为 有改动未add到暂存空间、有改动且存在了暂存空间但未提交到仓库、没有变动。具体的可以实操或查看廖雪峰的教程
git diff
如果git status 告诉你文件被修改过,就可以用git diff来查询具体改动了什么。
git diff 显示的格式是Unix通用的diff格式。具体的也可以实操或者查看廖雪峰的教程
git log [–pretty=oneline]
显示所有的提交历史。
–pretty=oneline 就是简略版的输出。
HEAD 指向的版本就是当前版本。
git reset --hard HEAD^
HEAD^ 就是指上一个版本,HEAD^^就是指向上上个版本,HEAD~100就是指向上100个版本。
git reflog
查看命令历史,以便确定回到未来的哪个版本。
使用场景是: 今天晚上将git回退到了之前的一个版本,关掉命令行窗口。第二天早上,突然不想回退了,但是此时通过git log 已经看不到那个版本的commitid了并且由于关掉过命令行窗口从而没法爬楼往上翻了。这时就可以使用git reflog,他会显示所有的命令历史,这里就有你今天晚上回退时的命令,这个命令中就会包含commitid。
工作区和暂存区
工作区就是.git存在的文件夹也是git进行管理的文件夹。
版本库(Repository),存在于工作区中,就是.git目录。
暂存区:版本库(.git目录)中存放了很多东西,其中最重要的就是称为stage(或则叫index)的暂存区,还有一个Git为你创建的指针master以及一个指向master的指针HEAD。
git checkout – filename
git checkout --file:是指丢掉工作区的所有修改,返回到上一次git add 或git commit的状态。
这里有两种状态:
- 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
git reset HEAD readme.txt
将送往暂存区的修改撤销掉,退回到工作区
git reset 既可以回退版本,也可以把暂存区的修改回退到工作区。当使用HEAD时,表示最新的版本。
也就是说使用场景是,当你把修改内容送到缓存区时,突然发现修改的东西有问题,不能commit。这时想撤销git add操作。怎么办呢?就是git reset HEAD filename。执行后,刚刚提交的修改就从缓存区消失了。我叫这个指令为撤销add指令。
又若是此时,你认为整个修改都是有问题的,不想要这个修改了,就可以执行上面的那条指令git checkout – filename
git rm filename
删除文件
若要删除某个工作区中的文件,想同步版本库时,不是输入git add filename,而是git rm filename。然后再git commit 到版本库来同步操作。
若是删除错了文件,想要恢复文件该咋办呢?如果还未git rm filename,那就git checkout filename就行了。若是已经git rm filename了,目前我尝试的就过是git checkout filename就无效了。
另外,没有添加到版本库(版本库中包含暂存区)就被删除了的文件,自然是无法恢复的。
git remote add origin git@github.com:HongyeZhao/learngit-new.git
把一个已有的本地仓库与在github上创建的仓库关联(这里就是learngit-new)
添加后,远程库的名字就是origin,这时Git默认的叫法,也可改成别的,但是origin这个名字更容易明白这就是远程库。
git push -u origin main
在关联了远程库后,将本地库上的所有内容推送到远程库上。
由于远程库是空的,所以第一次推送main分支时,加上了**-u**参数,这样Git不但会把本地的main分支内容推送到远程新的main分支,还会把本地的main分支和远程的main分支关联起来,在以后的推送或则拉取时就可以简化命令。
git push origin main
从本地main到最新修改推送至Github,这样,你就有了真正的分布式版本库。
git remote rm
若是添加时地址写错或想删除远程库,可以用此命令删除远程库。
在删除前最好是使用git remote -v来查看远程库的信息。比如:
zhaohongye@zhaohongyedeMac-mini learngit-new % git remote -v
origin git@github.com:HongyeZhao/learngit-new.git (fetch)
origin git@github.com:HongyeZhao/learngit-new.git (push)
然后根据名字删除:git remote rm origin
这里的删除其实是指接触本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何的改动,真正想要删除需要登录少github上找到删除按钮来删除。
git remote -v
查看远程库的信息
git clone git@github.com:HongyeZhao/gitskills.git
从远程仓库clone到本地库
git checkout -b dev
创建dev分支并切换到dev分支
-b表示创建并切换
git branch
查看分支信息
git checkout main
切换到main分支
git merge dev
合并dev分支到当前所在分支
git branch -d dev
删除dev分支
git switch -c dev
创建dev分支并切换到dev分支
checkou -b指令也能实现这个功能,但是为了更高的可读性,git提供了switch指令
git switch main
切换到main分支
分支合并时发生冲突的解决方法
情景:当合并分支时,发现你合并的那个分支所修改的文件,在当前分支也进行了修改,这时合并的话,git就会报conflict 冲突错误。
解决方法:git status会告诉我们冲突的文件,我们可以直接去查看冲突文件的内容。Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。你就可以权衡后进行修改然后保存,之后再add和commit到仓库。这时,冲突就解决了。两个分支到冲突文件的内容就都是你修改后的内容了。
git log --graph
查看分支合并图
$ git log --graph --pretty=oneline --abbrev-commit
* cf810e4 (HEAD -> master) conflict fixed
|\
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file
git merge --no-ff -m “merge with no-ff” dev
不使用fast-forward(快进模式)来合并分支。
–no-ff 表示禁用fast-forward
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
合并模式
fast-forward: 快进模式,这个模式下合并分支并删除了分支后,就会丢掉分支信息,就像分支没有存在过一样。
fast-forward模式下,合并就是将master(新版是main)指针直接指向dev指针处,不会留下dev分支的痕迹。
非fast-forward模式:
非fast-forward模式下,是这么个逻辑,合并时相当于做了一次从dev到commit到commit。会留下dev到痕迹。
分支策略
在工程的实际应用场景中,main(master)分支是稳定的,不会用来干活,只会在发布新版本时使用。
干活,也就是平时提交代码,一般都是在dev分支上,也可以说dev是不稳定的,代码的变动是大的。
然后每个成员都会有自己的分支,而自己写好的代码就会提交到dev分支。
在dev分支上测试代码可靠后,再由管理人员提交到main(master)进行版本发布。
git stash
隐藏当前工作现场
git stash list
查看隐藏的工作现场,查看stash内容。
git stash pop & git stash apply [stash id]
恢复隐藏的工作现场
使用pop恢复的话,stash内容并不删除,需要再使用git stash drop来删除stash信息。
使用apply的话,stash内容就会一并删除。
有一点是,两者都会回复隐藏空间,隐藏的工作现场都不会再对git隐藏。只是前者会保留stash信息而后者一并删除而已。
git cherry-pick 4c0fsd3
复制一个特定的提交到当前分支。
场景:当在master上出现了一个bug,你切换到master上对其进行了修改。但是你意识到这个bug在dev上同样也是存在的。那怎么办,再在dev上修改一次?如果此次修改了上千行代码呢?
解决方法就是git cherry-pick [commit id]。这里的commit id就是在master上修改完后的那一次提交。cherry-pick会在dev上进行一次commit,可以查看到这一次的commit id。
git branch -D
强行删除分支
当某个分支还没有被合并,却又想删除时,就可以用大D来删除这个分支。若不用—D,git会提示分支未被合并。
git push origin master/dev
想远程仓库合并当前分支(推送分支)。
git checkout -b dev origin/dev
当需要在远程仓库的dev分支上进行开发时,就必须创建远程origin的dev分支到本地,就可以使用上述命令来创建本地dev分支。
git pull
把远程库中的代码拉取下来。
当提交代码到远程库发生版本冲突或则有人在你之前提交过代码(你的代码不是最新版本)时,应该先把远程代码pull下来,然后在本地像处理合并冲突一样处理。
git branch --set-upstream-to=origin/dev dev
如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/。
git tag v1.0 [commit id]
在最新的或commit id 指向的cmmit处打上标签。
标签总是和某个commit挂钩,如果这个commit即出现在master分支也出现在dev分支,那么两个分支上都是可以看见标签的。
git tag
查看当前分支所有标签
git show < tagname >
查看标签信息。
git tag -a v0.1 -m “version 0.1 released” 1094adb
给某个标签添加说明文字。
-a 指定标签名 -m 指定说明文字
git tag -d v0.1
删除置顶标签。
git push origin v1.0
标签不会自动推送到远程仓库,若是想要推送某个标签到远程,使用上述命令。
git push origin --tags
一次性推送全部尚未推送到远程的本地标签。
git push origin :refs/tags/v0.9
删除远程的标签。
如果标签已经被推送到远程了,那么想要删除标签就会比较麻烦:
- 首先在本地删除 git tag -d v0.9
- 然后再删除远程标签 git push origin :ref/tags/v0.9
.gitignore文件
在.gitignore中编写需要忽略的文件。
有的文件我们必须存放在工作空间,但是不用推送给git。但是这些git status又会一直报Unstaged错误。这时就可以在.gitignore中编写规则来忽略掉这些文件。
忽略文件的原则是:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
- 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
github上提供了一些通用的规则:https://github.com/github/gitignore
git add -f App.class
强制添加文件到Git。
当文件被.gitignore忽略时,若想添加到暂存空间或提交,git会提示其已被忽略不能添加。这时就得加上**-f**参数来强制添加。
git check-ignore -v App.class
找出.gitignore文件中关于App.class的规则信息。
隐藏文件夹时,希望排除其中的个别文件
eg:
# 排除所有.开头的隐藏文件:
.*
# 排除所有.class文件:
*.class
# 不排除.gitignore和App.class:
!.gitignore
!App.class
git config --global alias.st status
给指令配置别名。
–global是针对当前用户起作用的,如果不加就只对当前仓库起作用。
配置信息在.git/config中的alias字段后(新版git貌似没有)。
当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中
git config --global alias.last ‘log -1’
为git last配置别名为log -1.
git last:显示最后一次提交信息。