【Git】常用命令与名词解释

查看仓库状态和文件更改

查看工作区状态:git status
与最近的一次add或commit比较文件的不同:git diff <file-name>
查看该文件与commit库中版本的变动情况:git diff HEAD -- <file-name>

查看过修改内容后,提交修改和提交新文件是一样的操作:git add,在git commit之前随时都可以用git status确认当前仓库的状态。
第三条命令在add过一次修改到缓存区后用。新到旧顺序:工作区、缓存区(add)、版本库(commit)

版本回退

回退到某版本:git reset --hard commit_id
向上回退n个版本:git reset --hard HEAD~{int n}
查看commit历史:git log
简短查看commit历史:git log --oneline
要重回reset前的版本:git reflog,查看HEAD变动的历史记录,以确定要回到未来的版本号。

HEAD指向的commit版本就是当前正在操作的commit版本,commit历史记录由上新下旧排列。

撤销修改

撤销工作区修改:git checkout -- <file-name>
撤销add到暂存区的修改:git reset HEAD <file-name>(似乎是返回到了再上一次git add的状态)。

checkout用于将工作区的文件撤销到上一次git addgit commit时的状态,丢弃本地修改。

删除文件

当已经commit后,本地工作区删掉了某些文件时,git status会提示有哪些文件相对于上一个版本被删除了,此时有两种选择:

从版本库中删除文件:git rm <file>
用版本库的文件替换掉工作区的文件:git checkout -- <file>

本地没删错时,git rm <file>,并git commit修改版本库状态。
删错文件时,用git checkout -- <file>把误删的文件还原到之前commit的状态,命令中一定记得加--,否则就是切换分支的命令了。

分支操作

查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
Fast forward合并:git merge --no-ff -m <description> <branch>
删除分支:git branch -d <name>
克隆仓库:git clone git@github.com:<username>/<repository>.git
推送到远程分支(远程分支不存在将自动创建):git push origin local_branch:remote_branch
git push origin branch-name

查看远程分支:git remote -v
创建远程分支到本地:git checkout -b <new-branch-name> origin/<branch>
获取远程分支git fetch origin <branch>
关联本地与远程分支:git branch --set-upstream-to=origin/<branch> <branch>
删除远程分支git push origin --delete origin/<btanch>

远程同步下来时,如果提示“Cannot update paths and switch to branch <branch> at the same time.”,那就先git fetch,再重试。

安装后配置

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

创建版本库

初始化仓库:git init
添加文件:git add <file>
添加所有文件:git add .
提交版本:git commit -m <description>

使用Commitizen规范化commit

$ npm install -g commitizen
$ commitizen init cz-conventional-changelog --save --save-exact

add的文件保存在暂存区(stage)
不加-m参数会启动文本编辑器以输入本次提交的说明。按i进入输入模式,输入内容不用带引号,输入完按esc退出输入模式,按shift + :进入命令模式,输入wq保存并退出。

因为Windows下的换行符是CRLF,Linux和Mac是LF,跨平台开发时会存在问题,commit时有可能会提示:

warning: LF will be replaced by CRLF   
fatal: CRLF would be replaced by LF

解决方法,修改core.autocrlf的值:

git config --global core.autocrlf true #这个是转换,也是默认值  
git config --global core.autocrlf input #貌似是上库转换,从库中迁出代码不转换  
git config --global core.autocrlf false  #这个一般是window上的,不转换

链接github

创建ssh key:ssh-keygen -t rsa -C "youremail@example.com"
添加远程库:git remote add origin git@github.com:<username>/<resposity>.git
关联本地与远程分支:git branch --set-upstream-to=origin/<branch> <branch>
第一次远程推送:git push -u origin master -f
非第一次推送:git push origin master
同步本地仓库:git pull --rebase origin master
远程库克隆为本地库:git clone git@github.com:<username>/<repository>.git

push时如果本地与远程文件结构差异太大,git push后加-f,强制覆盖已有分支。
如果提示remote origin already exists,则先git remote rm origin
在用户主目录下,查看是否有id_rsa(私钥)和id_rsa.pub(公钥)这两个文件,如果没有,输入上面的命令,创建ssh key,一路回车,无需密码,之后在github的ssh key设置里将.pub的文件中内容复制粘贴过去。
pull --rebase:如果本地库和仓库的文件不同步会提示推送失败,这时将远程仓库的文件与本地合并一下。

多人协作的流程:

  1. 首先,可以试图用git push origin branch-name推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功

Git鼓励大量使用分支。
使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

基础命令

使用git最基础的操作。

git-config 配置

用户配置

git config --global user.name "John EveryThing"
git config --global user.email yourusername@example.com

配置级别

--local 默认,高优先级:只影响本仓库
--global 中优先级:影响到所有当前用户的git仓库
--system 低优先级:影响到全系统的git仓库

git-init 初始化仓库

使用git status查看当前仓库的信息。
再使用git init来在一个文件夹创建一个git仓库,会在此文件夹创建一个.git文件夹。
这个目录默认是隐藏的,如果没有看到.git目录,用ls -ah命令显示。

git-status 对状态的跟踪

git对文件的状态跟踪分内容状态和文件状态。
内容状态:工作目录、暂存区、提交区。
文件状态:未跟踪、已跟踪。
所有这些状态之间都可以相互转化。

git-add 添加跟踪文件

git add *.*命令添加单个文件内容到暂存区,同时文件被跟踪。如果要添加当前目录下的所有文件,使用git add .命令。

gitignore 筛选添加文件

.gitignore在添加时忽略匹配的文件,仅作用于未追踪的文件。是一个筛选列表不能用于删除已经添加上的文件。在github已经有gitignore的官方忽略文档。

git-rm 从暂存区删除文件

git rm --cached仅从暂存区删除。
git rm从暂存区与工作目录删除。
git rm $(git ls-files --deleted)删除所有被跟踪,但是在工作目录被删除的文件。其中ls-files是到暂存区查找。

git-commit 从暂存区提交

git commit命令根据暂存区内容创建一个提交记录。
git commit -m 'initial commit'这个命令使用-m来在提交同时声明一个注释。
如果想要省略git add这一步直接提交,添加上-a参数,使用git commit -a -m 'full commit'命令,就会从工作目录直接提交到提交区。

git-log 查看历史信息

git log命令直接用于查看完整信息的提交历史。如果只想查看简短的配置信息,添加--oneline参数,即git log --oneline
如果想让查看的配置信息完整美观又简洁:

git log --color --graph --pretty=format:'%Cred%h%Creset 
-%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset --abbrev-commit

git config alias 配置别名

上面的配置信息太长了,用alias命令给自己定义缩短。

$ 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-diff 查看差异

直接使用git diff查看工作目录与暂存区的差异。
git diff -cached [<reference>]查看暂存区与某次提交差异,默认为HEAD(指向当前的提交),如果只是为了查看暂存区与上一次提交的差异,最后的这个参数可以不传。git diff HEAD
git diff <reference>查看工作目录与某次提交的差异,后面可以接两个参数。

image

git-checkout 撤销本地修改

git checkout -- <file>将文件内容从暂存区复制到工作目录,该操作会丢弃对暂存区内容的修改,使用时要小心。

git-reset 撤销暂存区内容

git reset HEAD <file>将文件内容从上次提交回退到暂存区。这样的操作会造成暂存区与工作目录文件的不一致,git会提示没有用add命令添加修改后的工作目录内容到暂存区。
如皋想将内容从上次提交后在提交区的内容复制到工作目录,使用gitcheckout HEAD -- <file>

git常用操作模型

git branch分支操作

分支的增删查改都靠它。
git branch <branchName>用来创建一个分支。
加入-d参数后git branch -d <branchName>可以用来删除指定的分支。

git checkout分支

通过移动HEAD检出版本,可用于分支切换。
git checkout <branchName>切换到目标分支。
加入-b参数后git checkout -b <branchName>会创建并切换到该分支。相当于先git branch后紧接一个git checkout
git checkout <reference>移动到任何一个commit id所在的引用对象上。
想快速回到上一个分支?使用git checkout -命令即可。
git branch -v显示现在所有的分支信息,分支前面带星号的就是当前HEAD指针指向的分支。
当checkout到一个不是分支指针所在的commit id后,此时的HEAD指针会指向一个非分支指针指向的位置,此时的状态称为detached(分离的) head。如果HEAD处于分离状态就要尽量避免在此状态提交东西,因为没有引用会指向这个提交记录,当HEAD重新回到master分支时刚才的提交都会被视为没有做引用,最后会在垃圾回收阶段被回收。因此当HEAD处于分离状态是不要进行写操作,而只是读取它的内容。由于HEAD指向的内容可以被复制到暂存区和工作目录,这是可以查看具体提交时的信息。

git reset回退

如果要回退到其他commit版本git reset --mixed <commit id>,最后的参数如果不填就回退到上一个commit版本。这样,HEAD,master都会移动到上一个commit,同时它们指向的内容会被复制到暂存区。
当使用head模式git reset --hard <commit id>,这部分内容除了被复制到暂存区,还会被复制到工作目录。
使用soft模式git reset --soft <commit id>,只有HEAD,master移动到这个commit上,对暂存区和工作目录不会有处理。这样上一个提交没有上传,也没有任何指针指向它了,有可能会被回收,成为了一个没有被索引的提交。怎么找回它呢?使用git reflog命令按顺序查看之前经过的所有commit路径,当前所在的位置就是列表的顶部,之前的commit会按序向下排,但是使用这个命令找回之前的commit要尽快,否则有的记录可能会丢失。

使用捷径

可以避免使用不直观的哈希值,用捷径,在下面的例子中,A表示HEAD指针,或分支名,或commit id。
A^表示A之上的父提交。A~n表示在A之前的第n次提交。


image

reset vs checkout

通过上面的内容可以看出reset和checkout直接有非常多的相似之处,下面列表以表示一下他们之间的区别。


image

git stash暂时保存

stash是一个独立在工作目录和暂存区之外的一个临时保存区。
git stash save 'push to stash area'会保存目前的工作目录和暂存区状态,并返回到干净的工作空间,同时保存一条注释。

使用git stash list查看stash区保存的所有信息。

然后使用git stash apply stash@{0}恢复stash区的内容到工作目录。最后使用git stash drop stash@{0}将stash上的记录删掉。
上面的两条操作可以合为stash pop一条命令完成,stash pop = stash apply + stash drop.

git merge合并分支

假设当前的HEAD指向master分支,同时还有个分支名为next,使用命令git merge next由于目前正在master分支所以省略了第二个参数,合并的结果会被复制到工作目录和暂存区,再会完成一次提交,这个提交节点的父节点有两个。来看一下这个合并后的节点的具体信息,使用git cat-gile -p HEAD命令,会发现有两个parent commit id,而next分支没有改变。
git merge next master合并后有很大的几率会提示两个节点中有冲突的文件。使用git status查看冲突的具体信息,在文件中做好修改后使用git add和git commit来解决。
假设从master分支创建了next分支,但是master分支没有向前移动仅仅是在next分支上做了修改,这时候使用git merge next命令会将master分支指向当前操作的next分支,这样操作就会变成线性,master分支其实与next分支合并了。
如果要避免fast-forward式的合并,使用git merge next --no-ff,这样原来的master分支会向前复制到一个新分支,并且与next分支合并。

git rebase修剪历史基线

首先现在有两个分支:master和feature

image

对如图所示的分支进行修剪基线操作git rebase master,git首先会找到两个分支节点的结束点,然后会将head所在的所有历史节点分别与master最后的节点进行合并并在master分支上依次将合并结果保存为新节点,这个过程是重演而不是复制,因为创建了2个新的节点。然后HEAD和feather分支都会指向最后的这次提交,master分支还保存在原来的位置,如下图:
image

然而并不是所有的变基操作都需要将原来的分支上所有节点都与master合并一次,所以这时候可以用git rebase --onto master <commit id>这样指定feather上某个特定的节点之后的节点与master的最后一个节点合并,指定的节点在合并时就被丢弃了。如图
image

rebase vs merge

rebase和merge没有孰好孰坏之说,最大的区别就是合并后是否是线性的。
切勿在公有分支使用rebase,比如之前例子中的master分支,否则rebase的后果会变成这样:


image

这样的master就变化到feather了。

git tag别名

如果要给一个commit id 设置一个别名就可以使用git tag v0.1 e39d0b2

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容