1. 程式人生 > >git中利用rebase來壓縮多次提交

git中利用rebase來壓縮多次提交

之前我們用git merge –squash來將分支中多次提交合併到master後,只保留一次提交歷史。但是有些提交到github遠端倉庫中的commit資訊如何合併呢?

歷史記錄

首先我們檢視一下master分支的提交歷史:

$ git log
commit 415a0be986a48113829b3c60ee2387c6dbdc81d8
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 20:11:29 2015 +0800

    10->1

commit ed09a6cbe0797275ceead3f8c8d829d01f0e604b
Author:
xuxu <xuxu_1988@126.com> Date: Mon Jan 26 19:57:17 2015 +0800 2015.01.26 commit 1821f6a1c1ed074fe886228cf33b3b3cb71819c4 Author: xuxu <xuxu_1988@126.com> Date: Mon Jan 26 19:53:28 2015 +0800 2015.01.26 commit cc779982fc61e82ec494d6a5654417fa7194d748 Author: xuxu <xuxu_1988@126.com
> Date: Mon Jan 26 19:40:24 2015 +0800 2015.1.26

我們看到上面有四次commit,如何將這個四次合併到一次呢?

壓縮

使用下面的命令,最後一個數字4代表壓縮最後四次提交。

git rebase -i HEAD~4

該命令執行後,會彈出vim的編輯視窗,4次提交的資訊會倒序排列,最上面的是第四次提交,最下面的是最近一次提交。

這裡寫圖片描述

我們需要修改第2-4行的第一個單詞pick為squash,這個意義為將最後三次的提交壓縮到倒數第四次的提交,效果就是我們在pick所在的提交就已經做了4次動作,但是看起來就是一次而已:

這裡寫圖片描述

然後我們儲存退出,git會一個一個壓縮提交歷史,如果有衝突,需要修改,修改的時候要注意,保留最新的歷史,不然我們的修改就丟棄了。修改以後要記得敲下面的命令:

git add .
git rebase --continue

如果你想放棄這次壓縮的話,執行以下命令:

git rebase --abort

如果所有衝突都已經解決了,會出現如下的編輯視窗:

這裡寫圖片描述

這個時候我們需要修改一下合併後的commit的描述資訊,我們將其描述為helloworld吧:

這裡寫圖片描述

儲存退出後會看到我們完整的資訊:

$ git rebase -i HEAD~4
[detached HEAD 9097684] helloworld
 Author: xuxu <[email protected]126.com>
 Committer: unknown <hui.qian@HuiQianPC.spreadtrum.com>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

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

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 9 files changed, 25 insertions(+), 11 deletions(-)
Successfully rebased and updated refs/heads/master.

現在我們來檢視一下歷史:

$ git log
commit 90976848524251b0a62376a9e45ea5c8aae25d87
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:40:24 2015 +0800

    helloworld

commit f57da9460196b950036fe4c2c8f7e4c9131ee04e
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:38:27 2015 +0800

    2015.01.26

commit 64104e057f48d6dd0e432af8b55cbccd0a09ee63
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 19:31:42 2015 +0800

    2015.01.26

commit 8499d4fa23c4395660d21e0b7dca873a7a3ef2b8
Author: xuxu <xuxu_1988@126.com>
Date:   Mon Jan 26 18:58:40 2015 +0800

    2015.01.26

歷史很清楚的顯示出了我們的壓縮成功了。

同步到遠端倉庫

那麼這個時候我們的github上的資訊又是如何呢?

這裡寫圖片描述

github上的提交歷史還是之前的,如何更新我們壓縮後的歷史記錄呢?

我們採用git push 試試:

To https://github.com/DoctorQ/AndroidTestScrpits.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/DoctorQ/AndroidTestScrpit
s.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

被拒絕了,因為我們合併的歷史記錄已經在遠端倉庫之前了,你無法覆蓋它。那怎麼辦?如果你確定你的合併過程都是正確無誤的,那麼就可以強制push:

$ git push -f
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

In Git 2.0, Git will default to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 1, done.
Writing objects: 100% (1/1), 232 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/DoctorQ/AndroidTestScrpits.git
 + 415a0be...9097684 master -> master (forced update)

我們成功了。。現在來看看以下github的歷史記錄,以及更新了。

這裡寫圖片描述

遺留問題

1.這個方式的侷限性是,我無法單獨建立一個分支,然後在分支上做壓縮動作,再合併到master上,在master上直接操作就存在很大的風險。也可能是我暫時還不會這麼做吧,希望以後能找到答案。
2.直接強制的push到遠端倉庫也會存在問題,別人pull下來後是不是也會有問題。這個也需要探究
3.這種方式可以適用在本地分支之間的合併,你在dev分支中做了很多開發工作,修改歷史很多,現在你開發完成了,你就要合併到master分支,然後提交到遠端倉庫。這個時候你可以用上面的流程先把dev的歷史記錄壓縮一下,然後合併到master中。如果你是處在協同開發環境下,你還需要主要經常做遠端倉庫同步到master的動作,master的更新再rebase到dev分支。也需要探究

相關推薦

git利用rebase壓縮提交

之前我們用git merge –squash來將分支中多次提交合併到master後,只保留一次提交歷史。但是有些提交到github遠端倉庫中的commit資訊如何合併呢? 歷史記錄 首先我們檢視一下master分支的提交歷史: $ git log

利用rebase壓縮提交

  我們可以用Git merge –squash來將分支中多次提交合併到master後,只保留一次提交歷史。但是有些提交到github遠端倉庫中的commit資訊如何合併呢? 歷史記錄 首先我們檢視一下master分支的提交歷史: $ git log commit 415a

快取檔案,瞭解git add對同一個檔案分提交的騷操作

場景: 我們在專案開發過程中, 有時候會遇到經理開始說了兩個需求, 我們在專案的基礎上直接將兩個需求做完了, 正當我們沉浸於提交一天的成果感覺人生已經達到了巔峰的氣氛中時, 經理說先上一個一個需求, 另一個需求暫時先不上. 暫且不提心情的落差, 放下了2米4的大砍刀之後,仔細分析了索

在Angular利用trackBy提升性能

trac () str -m return info 新的 第一個 大量 在Angular的模板中遍歷一個集合(collection)的時候你會這樣寫: <ul> <li *ngFor="let item of collection">{{ite

python利用字典一鍵

from collections import defaultdict d = defaultdict(list) d['a'].append(1) d['a'].append(2) d['b'].append(4) d = defaultdict(set) d['a'].add(1)

spring載入不到.properties屬性問題(spring類:PropertyPlaceholderConfigurer出現)

  spring在載入properties時出現的問題 在spring.xml中將redis.properties Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreE

Vuejs在v-for,利用index對第一項新增class的方法

1.為li列表首項新增選中樣式: <li v-for="(items,index) in currentImgList" class="imgLiClass" :class="{'active': !index}"></li> 或者 <li v-for="(

RNN利用LSTM預測sin函式

前言:這個例子是用LSTM來預測sin函式的問題,期間遇到了一個了十分致命的問題,就是構造資料的時候,沒有把資料構造成序列,所以一直在報維度上的錯誤,以後對時序問題的預測要格外注意資料是否是序列的資料,否則很難檢查出問題,中間的問題其實比較好看出來,一除錯就能解決。 這個例

sql優化:with as 作 union all的子查詢 避免掃描表

語法: 1.結構: with 別名 as ( 公共sql片段 ) 2.CTE(公共表示式)後面必須直接緊跟使用CTE的SQL語句,否則失效; 如: 1) with cr as (select CountryRegionCode from person.CountryR

在Unity3d使用GZip壓縮傳輸資料

因為Unity中的.net支援是有限制的,所以C#自帶的GZip的壓縮方法不能夠使用。          可以到下面網址去下載一個專門的dll來處理資料的GZip壓縮: 將下載的dll檔案

Linux使用gzip壓縮/解壓 *.gz檔案

gzip 是linux中常見的壓縮/解壓工具,最常見的使用物件是*.gz格式的檔案,這裡簡單介紹下它最常見的用法, GZIP(1) General Commands Manual GZIP(1)NAME      gzip, gunzip, zcat - compress

c++利用巨集宣告和定義變數

假設我們要定義一個配置類,類中包含了很多的配置成員,有一種通過巨集的方法可以讓我們方便的維護繁多的成員 在一個類中,定義一個變數需要型別,建構函式中給出的初始值。我們需要能夠像指令碼語言一樣進行配置變數: tconfig.h OPTION(m_data,OPT_INT,-1) OPTION(m_value

AngularJS 利用 Interceptors 統一處理 HTTP 的錯誤

Web 開發中,除了資料操作之外,最頻繁的就是發起和處理各種 HTTP 請求了,加上 HTTP 請求又是非同步的,如果在每個請求中來單獨捕獲各種常規錯誤,處理各類自定義錯誤,那將會有大量的功能類似的程式碼,或者使用醜陋的方法在每個請求中呼叫某幾個自定義的函式來處理。這兩種

VIM利用巨集實現插入一列遞增或遞減序號

  經常遇到需要在文字中插入序號的情況,網上有很多方法,有時還要用到外掛。在這裡偶介紹偶經常使用的方法:利用VIM的巨集錄製功能來插入一列遞增或遞減序號。其實VIM的巨集錄製功能確實比較實用,可以完成很多工,省掉好多外掛。 這裡舉例:   需要在一個已經寫好的文字中插入行

GIT 同時 push 程式碼到個遠端倉庫

需求: 原生代碼需要 push 到兩個遠端倉庫中,如同時push到 github.com 和 git.oschina.net 兩個倉庫 方案: 修改原生代碼中 .git/config

利用介面實現

I介面 i = new MyClass();             i.funk();             Console.ReadKey(); interface I介面     {         void funk();     } class MyClass:

Linux利用logrotate對log檔案進行轉儲

使用logrotate對日誌檔案轉儲,按時或者按大小。 logrotate簡介 NAME logrotate - rotates, compresses, and mails system logs SYNOPSIS

SpringMVC利用@InitBinder對頁面資料進行解析繫結

在使用SpingMVC框架的專案中,經常會遇到頁面某些資料型別是Date、Integer、Double等的資料要繫結到控制器的實體,或者控制器需要接受這些資料,如果這類資料型別不做處理的話將無法繫結。       解決方法:使用註解@InitBinder來解決這些問題,這樣

Ubuntu使用pyenv安裝版本的Python

安裝pyenv 選擇pyenv的安裝路徑,Ubuntu系統可以選擇安裝在home目錄下,在命令視窗輸入如下命令: $ git clone https://github.com/pyenv/pyenv.git ~/.pyenv 定義環境變數,在命令視窗依

Matlab利用null函式解齊線性方程組

摘自:http://blog.csdn.net/masibuaa/article/details/8119032 有齊次線性方程AX=0,且rank(A)=r<n時,該方程有無窮多個解,可以用matlab 中的命令 x=null(A, r)求其基礎解系.其中:r=ra