Git指令学习笔记

rebase

多人在同一个分支上协作时,很容易出现冲突。即使没有冲突,后push的童鞋不得不先pull,在本地合并,然后才能push成功。那么怎么才能让提交历史变得干净,易读呢?可以使用rebase对某一段线性提交历史进行编辑、删除、复制、粘贴;因此,合理使用rebase命令可以使我们的提交历史干净、简洁!




$ git rebaseFirst, 

rewinding head to replay your work on top of it...Applying:add commentUsingindex info to reconstruct a base tree...Mhello.pyFallingback to patching baseand3-way merge...Auto-merging hello.pyApplying:add authorUsingindex info to reconstruct a base tree...Mhello.pyFallingback to patching baseand3-way merge...Auto-merging hello.py


reset

git reset命令用于将当前HEAD复位到指定状态。一般用于撤消之前的一些操作(如:git add,git commit等)。

git reset [-q] [] [--] …​

git reset (--patch | -p) [] [--] […​]

git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []

在第一和第二种形式中,将条目从<tree-ish>复制到索引。 在第三种形式中,将当前分支头(HEAD)设置为<commit>,可选择修改索引和工作树进行匹配。所有形式的<tree-ish>/<commit>默认为HEAD。

这里的HEAD关键字指的是当前分支最末梢最新的一个提交。也就是版本库中该分支上的最新版本。

在git的一般使用中,如果发现错误的将不想暂存的文件被git add进入索引之后,想回退取消,则可以使用命令:git reset HEAD <file>,同时git add完毕之后,git也会做相应的提示,


Submodule

当项目越来越庞大之后,不可避免的要拆分成多个子模块,我们希望各个子模块有独立的版本管理,并且由专门的人去维护,这时候我们就要用到git的submodule功能。

常用命令

git clone <repository> --recursive 递归的方式克隆整个项目

git submodule add <repository> <path> 添加子模块

git submodule init 初始化子模块

git submodule update 更新子模块

git submodule foreach git pull 拉取所有子模块


创建project版本库,并提交readme.txt文件

git init --bare project.git

git clone project.git project1

cd project1

echo "This is a project." > readme.txt

git add .

git commit -m "add readme.txt"

git push origin master

cd ..

创建moduleA版本库,并提交a.txt文件

git init --bare moduleA.git

git clone moduleA.git moduleA1

cd moduleA1

echo "This is a submodule." > a.txt

git add .

git commit -m "add a.txt"

git push origin master

cd ..

在project项目中引入子模块moduleA,并提交子模块信息

cd project1

git submodule add ../moduleA.git moduleA

git status

git diff

git add .

git commit -m "add submodule"

git push origin master

cd ..

2. 克隆带子模块的版本库

方法一,先clone父项目,再初始化submodule,最后更新submodule,初始化只需要做一次,之后每次只需要直接update就可以了,需要注意submodule默认是不在任何分支上的,它指向父项目存储的submodule commit id。

git clone project.git project2

cd project2

git submodule init

git submodule update

cd ..

方法二,采用递归参数--recursive,需要注意同样submodule默认是不在任何分支上的,它指向父项目存储的submodule commit id。

git clone project.git project3 --recursive

 修改子模块

cd project1/moduleA

git branch

echo "This is a submodule." > b.txt

git add .

git commit -m "add b.txt"

git push origin master

cd ..

git status

git diff

git add .

git commit -m "update submodule add b.txt"

git push origin master

cd ..

更新子模块

方法一,先pull父项目,然后执行git submodule update,注意moduleA的分支始终不是master。

cd project2

git pull

git submodule update

cd ..

方法二,先进入子模块,然后切换到需要的分支,这里是master分支,然后对子模块pull,这种方法会改变子模块的分支。

cd project3/moduleA

git checkout master

cd ..

git submodule foreach git pull

cd ..

5. 删除子模块

网上有好多用的是下面这种方法

git rm --cached moduleA

rm -rf moduleA

rm .gitmodules

vim .git/config

删除submodule相关的内容,例如下面的内容

[submodule"moduleA"]      url =/Users/nick/dev/nick-doc/testGitSubmodule/moduleA.git

然后提交到远程服务器

git add .

git commit -m "remove submodule"


.reflog

  如果在回退以后又想再次回到之前的版本,git reflog 可以查看所有分支的所有操作记录(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录

Administrator@USER-20171026MG MINGW64 ~/Desktop/lyf (master)

$ git reflog

e1bdff6 (HEAD -> master) HEAD@{0}: commit: 第二次提交

62e6739 HEAD@{1}: reset: moving to HEAD^

8113f0d HEAD@{2}: reset: moving to HEAD^

dc6bb4e HEAD@{3}: reset: moving to dc6bb4e

8113f0d HEAD@{4}: reset: moving to HEAD^

dc6bb4e HEAD@{5}: commit: my.txt增加44444内容

8113f0d HEAD@{6}: commit: 文件增加33333内容

62e6739 HEAD@{7}: commit (initial): my第一次提交



执行git blame;命令时,会逐行显示文件,并在每一行的行首显示commit号,提交者,最早的提交日期

给具体文件执行$git blame后的效果如下

6c2414fb (liangfei 2014-05-12 05:32:01 -0400  1) from markdown import markdown

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  2) from django.shortcuts import render

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  3) from django.core.paginator import Paginator, InvalidPage, EmptyPage

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  4) from blog.models import Post, Category

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  5)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  6)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  7) def category(request, cat_name, page_num=1):

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  8)    if cat_name.lower() == 'home':

be442bb4 (liangfei 2014-05-09 10:26:27 -0400  9)        posts = Post.objects.all().order_by('-date')

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 10)    else:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 11)        posts = Post.objects.all().filter(category__name=cat_name).order_by('-date')

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 12)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 13)    paginator = Paginator(posts, 3)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 14)    try:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 15)        page = int(page_num)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 16)    except ValueError:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 17)        page = 1

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 18)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 19)    try:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 20)        posts = paginator.page(page)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 21)    except (InvalidPage, EmptyPage):

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 22)        posts = paginator.page(paginator.num_pages)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 23)

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 24)    for post in posts:

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 25)        post.body = markdown(post.body)

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 26)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 27)    return render(request, 'blog/index.html',

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 28)                  {

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 29)                      'posts': posts,

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 30)                      'cat_now': cat_name,

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 31)                      'cat_all': map(lambda cat: cat.name, Category.objects.all())

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 32)                  })


git stash 的作用

git stash用于想要保存当前的修改,但是想回到之前最后一次提交的干净的工作仓库时进行的操作.git stash将本地的修改保存起来,并且将当前代码切换到HEAD提交上.

通过git stash存储的修改列表,可以通过git stash list查看.git stash show用于校验,git stash apply用于重新存储.直接执行git stash等同于git stash save.



开发到一半,同步远端代码

当你的开发进行到一半,但是代码还不想进行提交 ,然后需要同步去关联远端代码时.如果你本地的代码和远端代码没有冲突时,可以直接通过git pull解决.但是如果可能发生冲突怎么办.直接git pull会拒绝覆盖当前的修改.

遇到这种情况,需要先保存本地的代码,进行git pull,然后再pop出本地代码:

git stash

git pull

git stash pop

工作流被打断,需要先做别的需求

当开发进行到一半,老板过来跟你说"线上有个bug,你现在给我改好,不然扣你鸡腿".当然,你可以开一个新的分支,把当前代码提交过去,回头再merge,具体代码如下

繁琐的工作流示例# ... hack hack hack ...git checkout -b my_wip git commit -a -m"WIP"git checkout master edit emergency fix git commit -a -m"Fix in a hurry"git checkout my_wip git reset --soft HEAD^# ... continue hacking ...

我们可以通过git stash来简化这个流程

正确姿势# ... hack hack hack ...git stash//保存开发到一半的代码edit emergency fix git commit -a -m"Fix in a hurry"git stash pop//将代码追加到最新的提交之后# ... continue hacking ...

提交特定文件

如果对多个文件做了修改,但是只想提交几个文件,或者想先暂时保存几个修改,测试其他文件的执行结果.可以通过git stash save --keep-index来进行.

# ... hack hack hack ...git add --patch foo//只将第一部分加入管理the indexgit stash save --keep-index//将其余部分保存起来edit/build/test first part git commit -m'First part'//提交全部的git管理中的代码git stash pop//继续进行存储代码的工作# ... repeat above five steps until one commit remains ...edit/build/test remaining parts git commit foo -m'Remaining parts'

恢复被错误clear/drop的存储

如果因为失误对存储仓库进行了clear或者drop操作,在一般机制下是不能恢复的.但是可以通过以下指令来获取仍在仓库中的,但是已经不可获取的存储列表

git fsck --unreachable |grep commit | cut -d\  -f3 |xargs gitlog--merges --no-walk --grep=WIP



git fetch

git fetch从远程分支拉取代码。

fetch常结合merge一起用,git fetch + git merge == git pull

一般要用git fetch+git merge,因为git pull会将代码直接合并,造成冲突等无法知道,fetch代码下来要git diff orgin/xx来看一下差异然后再合并。

作者:忆飞

链接://www.greatytc.com/p/a5c4d2f99807

来源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

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

推荐阅读更多精彩内容