Git:基本和常用操作

使用git管理本机目录

git init

在当前目录下使用git init ,即可将此目录变成git可以管理的仓库


目录下有了变动之后,例如新增了一个txt文件

用命令git add告诉Git,把文件添加到仓库:


执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。

注意,一般都是用 git add .   来把当前目录所有文件都添加


然后第二步,用命令git commit告诉Git,把文件提交到仓库:


-m后是本次提交的额外说明


修改文件后,使用git status查看当前状态会发现:


可以看出 有一个文件有修改 但还没有提交

进一步 可以使用git diff 看一下具体是什么修改:


看到 有两版的readme文件 b版本的readme新增了一行、

此时使用Git add:


可以看到对readme的修改已经将要被提交

再使用git commit,然后查看状态:

在实际工作中,可能此仓库被修改和提交无数次,

这时,会使用 git log 来查看每个版本:


如果想回退之前的版本:

使用:git reset--hard HEAD^

其中 HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^ 当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。


如果后悔了 想回到之前最新的版本,如果刚才的commit id还在 就可以:

git reset--hard  1094a(然后按tab自动补全 不需要全部打)


但如果刚才的窗口关了 忘了版本id了(此时用git log 已经看不到刚才的id了 因为已经回到了上一版本)

git有一个工具来记录你的所有命令:

git reflog


可以看到 最新版本的id应该是以7c8d开头的

从而就找到了id



工作区和暂存区:


工作区(Working Directory)

就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:


版本库(Repository)

工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。


前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。


add把工作区的东西添加到暂存区


commit 把暂存的东西 提交到真正的分支,从而暂存区就叫“clean”


撤销修改:


工作区某东西被修改或者删除 但是不想要这个修改或者删除了 因为版本库里还有这个文件的原本 就可以直接回复 (用 git status时,会告诉你,git checkout -- file可以丢弃工作区的修改 ):


工作区某东西被修改或者删除 已经git add了但不想要这个修改了 用git reset HEAD file来回到场景一,然后恢复工作区就好


使用github作为远程仓库:

在github上创建好仓库

然后,在本地的仓库下运行命令:

git remote add origin git@github.com:hilbertletanger/myfirstnow.git

这里 第一个git@github.com永远不用变 冒号后是你github上的账号和仓库,例如上面这个对应:


所以,如果想连接到另外的新建的远程仓库,改myfirstnow为新仓库名就行


添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

下一步,就可以把本地库的所有内容推送到远程库上:
git push -u origin master

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。


从现在起,只要本地作了提交,就可以通过命令:

git push origin master

来把本地master分支的最新修改推送至GitHub



分支管理:

创建dev分支,然后切换到dev分支:

git checkout -b dev

加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev

$ git checkout dev

用git branch命令查看当前分支


现在,我们把dev分支的工作成果合并到master分支上:

git merge dev

命令用于合并指定分支到当前分支


合并完成后,就可以放心地删除dev分支了:

git branch -d dev


我们注意到切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。

实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来切换分支:

创建并转到:

git switch -c dev

直接切换

git switch dev


解决冲突:

如果master分支 和dev分支各自有了新的提交 成为:


这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:


此时,再打开text.txt会发现


git已经自动在文本中做处理 标记出冲突的行 以及其来源是那个branch

只需要自己手动修改这个文件 保留真正想要的(然后记得要add 和commit ),然后再merge就好

合并完就可以删除被合并的branch了


当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。

用git log --graph命令可以看到分支合并图。


分支管理策略


在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

所以,团队合作的分支看起来就像这样:



注意:合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

git merge --no-ff -m"merge with no-ff"dev

加上-m 是因为这时会创建一个新的commit 所以把commit的描述也写进去


修复bug时 保存当前工作状态:

每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交:

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?

幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:


现在,用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。

首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:


修改后 add commit

然后切换回master 合并issue-101分支 并且删除原分支


现在回到dev分支干活:

git stash list 查看刚才的现场

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了


在master分支上修复了bug后,我们要想一想,dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。

那怎么在dev分支上修复同样的bug?重复操作一次,提交不就行了?

有木有更简单的方法?

有!

同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101这个提交(也就是我们之前在issue101分支上 修复bug后做的commit)所做的修改“复制”到dev分支。注意:我们只想复制4c805e2 fix bug 101这个提交所做的修改,并不是把整个master分支merge过来。

为了方便操作,Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:



远程协作:


推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

git push origin master


直接从远程库克隆 默认只有master分支 如果想要其他分支比如dev:

git checkout -b dev origin/dev

实际是创建一个dev分支 然后把远程的dev分支覆盖到本地


如果别人已经对远程dev推送了提交  而你也想在dev上做修改 然后试图推送到远程

推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

直接Git pull也会失败 因为没有指定本地dev和远程origin/dev的连接 所以需要先

git branch--set-upstream-to=origin/dev dev

然后再 git pull

然后手动合并merge  解决冲突后 git commit 然后git push

因此,多人协作的工作模式通常是这样:

首先,可以试图用git push origin <branch-name>推送自己的修改;

如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

如果合并有冲突,则解决冲突,并在本地提交;

没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。


标签:

在Git中打标签非常简单,首先,切换到需要打标签的分支上:

然后,敲命令git tag <name>就可以打一个新标签:

用 git tag可以查看所有标签

默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?

方法是找到历史提交的commit id,然后打上就可以了:

git tag v0.9  f52c633

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:


如果标签打错了,也可以删除:

如果要推送某个标签到远程,使用命令git push origin <tagname>:


Fetch相关

想基于别人的仓库开发

首先在github上,fetch别人的仓库,现在,你拥有了一个


克隆此仓库到本地

这时,在本地修改后,如果直接git push 会让你输入用户名和密码 这是因为git clone的时候使用的是http链接而不是ssh链接

方法:

首先git remote rm origin  移除已经添加的远程连接

然后 git remote add origin git@github.com:hilbertletanger/RIO-SAM.git  用ssh方式建立其链接

这时,用git push origin master就能正常运行了

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

推荐阅读更多精彩内容