-Git 使用技巧 总结 MD
目錄
- 目錄
- Bash下的快捷操作
- 常用命令
- 常用操作
- 移動光標
- 刪除輸入內容
- Tab鍵的作用
- Git默認Vim編輯器基本使用
- Git 使用場景
- 合并多個commit:rebase -i【s】
- 刪除多個commit:rebase -i【d】
- 修改多個commit:rebase -i【r】
- 挑選多個commit:cherry-pick
- 使用 git branch -d 刪除分支的條件
- 解決 push 時提示 Everything up-to-date 問題
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目錄
Bash下的快捷操作
常用命令
- cd:change directory 改變目錄,不帶參數時默認進入【/c/Users/當前用戶】目錄
- cd ..:回到父目錄
- cd aaa:進入指定目錄,可以是相對目錄或絕對目錄
- pwd:打印工作目錄路徑
- ls和ll:列出當前目錄中的所有文件
- touch aaa.txt:在當前目錄下新建一個文件
- mkdir aaa:在當前目錄下新建一個目錄
- rm aaa.txt:刪除指定的文件
- rm -r aaa:刪除指定的目錄,參數r為recusive是遞歸的意思
- mv aaa.txt bbb:將文件移到指定目錄下
- q:結束一個命令
常用操作
- 復制內容:選中后就已經復制了(勾選了"選擇時復制"),或 Ctrl + Insert
- 粘貼內容:點擊鼠標中鍵,或 Shift + Insert
- 搜索內容:Alt + F3,按Enter或Shift + Enter選中下/上一個匹配內容
- 縮放文字:Ctrl + 【+/-】
- 窗口清屏:Alt + F8(重置),cmd 下的命令是 cls
- 窗口全屏:Alt + F11,再按一次還原
移動光標
- 一個字符一個字符向左/右移動光標:Ctrl + B/F
- 一個單詞一個單詞向左/右移動光標:Alt + B/F
- 移動光標到整條命令的起始/結束位置:Ctrl + A/E(ahead end)
刪除輸入內容
- 刪除光標左/右側的字符:Ctrl + H/D(或backspace鍵、delete鍵)
- 刪除光標左/右側的單詞:Ctrl + W,Alt + D
- 刪除光標左/右側的所有內容:Ctrl + U/K
Tab鍵的作用
- 輸入內容(文件名或命令)的前幾個字母時,按tab,如果有內容可以匹配,它就會顯示出完整的內容
- 如果有多個內容匹配到,它會顯示最先找到的一個,再按一次tab,它就會匹配的下一個
- 我們可以不停地按Tab鍵在匹配的內容中來回切換,直到找到我們文件名為止
Git默認Vim編輯器基本使用
Git默認的編輯器是Vim,在很多情境下會遇到它,例如commit提交,如果提供-m指令,直接在后面寫上此次提交的說明信息;如果不提供-m指令,默認將會彈出Vim編輯器,如下:
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.此編輯器和平時所用編輯器差距很大,Vim編輯器命令很多,下面介紹一下簡單操作,以完成基本的Git操作。
Vim主要有如下兩種模式:
- Normal 模式:命令模式,按 ESC 或 Ctrl + [ 進入,此模式下無法輸入內容,但是可以復制、黏貼、保存、退出
- :w表示保存
- :q表示離開,如果未保存會有提示
- :q!表示不保存離開
- :wq表示保存并離開(用的最多)
- Insert 模式:編輯模式,點擊i、a 或 o 鍵可以進入
Git 使用場景
合并多個commit:rebase -i【s】
基本步驟:
- 執行git rebase -i HEAD~影響的最少commit數或git rebase -i 前一個commitId
- 將需要合并的那條commit前面的pick改為s,保存后退出
- 修改commit日志,保存后退出
以下是詳細操作
在使用 Git 作為版本控制的時候,我們可能會由于各種各樣的原因提交了許多臨時的 commit,而這些 commit 拼接起來才是完整的任務。那么我們為了避免太多的 commit 而造成版本控制的混亂,通常我們推薦將這些 commit 合并成一個。
首先你要知道自己想合并的是哪幾個提交,可以使用 git log 命令來查看提交歷史,假如最近 4 條歷史如下:
commit 8b5cbda494a68582164048159e605e731f357444 (HEAD -> master) commit a472755058e78a33595390f87d03d855fc25da84 commit 6ab13045d47157842961fae70baa7ef25e1856b1 commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)歷史記錄是按照時間排序的,時間近的排在前面。
如果想要合并第 2 和第 3 條記錄,有兩個方法,這兩個方法效果是一致的:
- 從HEAD版本開始往過去數 3 個版本
- 指名要合并的版本之前的版本號
請注意 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f 這個版本是不參與合并的,可以把它當做一個坐標
執行了 rebase 命令之后,會彈出一個窗口,內容如下:
pick 6ab1304 11111111 pick a472755 222222222 pick 8b5cbda 3333333# Rebase 00b8fe5..8b5cbda onto 00b8fe5 (3 commands) # # Commands: # p, pick = use commit # r, reword(改寫) = use commit, but edit the commit message # e, edit = use commit, but stop for amending(修正) # s, squash(塞入) = use commit, but meld into(融入) previous commit # f, fixup(修正) = like "squash", but discard(丟棄) this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out(被注釋掉的)可以看到,里面有詳細的命令提示。我們將需要合并的那條commit前面的pick改為s,之后保存并關閉文本編輯窗口即可。改完之后文本內容如下:
pick 6ab1304 11111111 s a472755 222222222 pick 8b5cbda 3333333然后保存退出。如果沒有沖突,或者沖突已經解決,則會出現如下的編輯窗口:
# This is a combination of 2 commits. # This is the 1st commit message:11111111# This is the commit message #2:222222222# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit(空消息會終止提交). # # Date: Sun Jul 7 21:14:02 2019 +0800 # # interactive(互動) rebase in progress; onto 00b8fe5 # Last commands done (2 commands done): # pick 6ab1304 11111111 # squash a472755 222222222 # Next command to do (1 remaining command): # pick 8b5cbda 3333333 # You are currently rebasing branch 'master' on '00b8fe5'. # # Changes to be committed: # modified: build.gradle如果不做任何修改的話,默認是保留兩次 commit 的日志,中間有一個空白行,你可以隨意修改合并后的日志。
保存并退出后再次輸入 git log 查看 commit 歷史信息,你會發現這兩個 commit 已經合并了。
commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (HEAD -> master) commit 052ea3ea0b30c375e79ad9e891c5e5202768b11b commit 00b8fe51079ac0ba1d5a87e9c0b51c9e851d233f (origin/master, origin/HEAD)雖然我們只是合并了第 2 條和第 3 條的commit,但是第 1 條的 commitId 也變了。
如果有沖突,需要修改。修改的時候要注意,保留最新的歷史,不然我們的修改就丟棄了。
修改以后要記得敲下面的命令:
git add . git rebase --continue如果你想放棄這次壓縮的話,執行以下命令:
git rebase --abort刪除多個commit:rebase -i【d】
和上面的操作基本一致。
例如我的提交歷史如下:
commit 831be8ec644c4943374adca03880732c7ec9d6bd (HEAD -> master) commit 6a8ecb529a4ec6b6e0fc83e0789043b7785e73fe commit 3b228d8af9e52806c106ef3f0c27e622b5407faf commit 9adb987d31f11f8d38f8d817096d2d21a7390a1d (origin/master, origin/HEAD)我想刪除第2條和第3條提交,基本步驟:
- 執行git rebase -i HEAD~影響的最少commit數或git rebase -i 前一個commitId
- 將需要刪除的那幾條commit前面的pick改為d,保存后退出
- 修改commit日志,保存后退出
注意,這個操作感覺出現沖突的概率比較大,例如我上面三次commit都是在同一個文件的第一行插入一行新的文字:
//添加3 //添加2 //添加1執行rebase后就會提示沖突了:
git rebase -i 9adb987d31f11f8d38f8d817096d2d21a7390a1d Auto-merging build.gradle CONFLICT (content): Merge conflict in build.gradle error: could not apply 831be8e... 333Resolve all conflicts manually手動, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort".Could not apply 831be8e... 333解決沖突后按以下操作:
git add . git rebase --continue可以發現,相應 commit 都還原了,包括修改的文件以及提交的commit記錄。
修改多個commit:rebase -i【r】
和上面的操作基本一致。
例如我的提交歷史如下:
commit 442... (HEAD -> master) commit 5a1... commit 305... commit f30... (origin/master, origin/HEAD)我想修改第2條和第3條提交,基本步驟:
- 執行git rebase -i HEAD~影響的最少commit數或git rebase -i 前一個commitId
- 將需要修改的那幾條commit前面的pick改為r,保存后退出
- 每個改為reword的提交都會提示你一個編輯窗口讓你修改commit日志,修改保存后退出
注意,修改后會生成新的commitId
挑選多個commit:cherry-pick
cherry-pick 的翻譯是擇優挑選,使用git cherry-pick命令,可以選擇將現有的一個或者多個提交的修改引入當前內容。
cherry-pick 官方文檔
git cherry-pick <commitid> <commitid>挑選多個提交合并,提交之間用空格相隔。
git cherry-pick <start-commit>..<end-commit>挑選一個范圍內的多個提交合并,不包含start-commit(最早的提交),包含end-commit(最近的提交)。另外要注意兩個 commit 之間要求有連續關系的,并且前者要在后者之前,順序不能顛倒。
git cherry-pick <start-commit>^..<end-commit>這個和上面一樣,區別就是加了一個^符號,就變成閉區間了,包含 start-commit。
git cherry-pick <branch name>挑選 branch 最頂端的提交。
git cherry-pick --continue //繼續下個操作 git cherry-pick --quit //退出 git cherry-pick --abort //停止本次操作當 cherry-pick 多個 commit 時,假設遇到沖突:
- --continue繼續進行下個
- --quit結束 cherry-pick 操作但是不會影響沖突之前多個提交中已經成功的
- --abort直接打回原形,回到 cherry-pick 前的狀態,包括多個提交中已經成功的
使用 git branch -d 刪除分支的條件
參考:git branch -d 和 git branch -D 的區別
結論:
在使用-d刪除分支時,該分支必須完全和它的上游分支merge完成,如果沒有上游分支,必須要和HEAD完全merge。
出現的案例一
- 1、現有一個本地分支 v0.1,我做一些修改后 commit (沒有 commit或stash 是不能切換到其他分支的)
- 2、然后切到其他分支(因為不能刪除當前分支)后刪除 v0.1 試試 ,可以發現刪除失敗
3、然后切到 v0.1 上,將修改推送到遠端:git push origin v0.1
4、然后再切到其他分支后刪除 v0.1 試試,可以發現刪除成功,但是有警告
上面的步驟進行一些優化:
4、假如我們后面刪除前是切到了 master 分支,所以當前HEAD為 master 分支("所以"這個詞用的對嗎?)
5、將 v0.1 上的修改 merge 過來git merge v0.1,然后再刪除 v0.1 試試,可以發現刪除成功且沒有警告
出現的案例二
- 1、首先我基于當前分支 v0.1 創建了一個分支 v0.1_copy:git branch v0.1_copy(此分支并沒有上游分支)
- 2、然后切到 v0.1_copy 上,并進行一些修改,然后 commit
- 3、然后切到 v0.1 后刪除 v0.1_copy 試試,可以發現刪除失敗
5、然后切到 v0.1 上,并將 v0.1_copy 上的修改 merge 過來git merge v0.1_copy
6、然后再刪除 v0.1_copy 試試,可以發現刪除成功且沒有警告
總結
簡單來說就是這么一個設計思想:
- 如果一個分支有和遠端分支關聯(有上游分支),那么在刪除此分支前需要將此分支上的commit push到遠端,不然在分支被刪除時在其上所做的 commit 也一并被刪除了,設計者認為這樣的操作風險極大
- 如果一個分支沒有和遠端分支關聯(沒有上游分支),由于在此分支上的 commit 不能 push 到遠端,那么為了防止 commit 也一并被刪除了,設計者要求必須要和HEAD完全merge才能刪除
總之一句話,刪除分支不能導致有任何已做的 commit 無法追蹤,如果你想這么做,必須使用 -D 達到你的目的
解決 push 時提示 Everything up-to-date 問題
參考 stackoverflow 上的答案
1、現在有一個本地分支 v0.1,且其和遠端分支 v0.1 關聯,此時你在本地 v0.1 做的任何修改都可以通過git push origin v0.1推到遠端,這很正常
2、然后你通過git branch v0.1_backup創建了一個備份分支,然后 checkout 到此分支后做了一些修改,當你 commit 后 push 到遠端的 v0.1 時問題就出現了
git push origin v0.1 Everything up-to-date其實這里的 "Everything up-to-date(最新)", 的含義是:
"all the branches you've told me how to push are up to date".
也就是說遠端的v0.1是最新的
并且此時其實并沒有push到遠端的
git status On branch v0.1_backup Your branch is ahead of 'origin/v0.1' by 1 commit.原因是很簡單的,分支 v0.1_backup 并沒有和遠端分支關聯
$ git branch -vvmaster de18ed6 [origin/master] 修改1v0.1 03cb1c6 [origin/v0.1] 修改2 * v0.1_backup 88eb433 修改33、現在你通過git branch -u origin/v0.1 v0.1_backup可以將其和遠端的 v0.1 關聯
$ git branch -vvmaster de18ed6 [origin/master] 修改1v0.1 03cb1c6 [origin/v0.1] 修改2 * v0.1_backup 88eb433 [origin/v0.1: ahead 1] 修改34、然后再 push 到遠端的 v0.1 會發現,問題依舊
解決方式有三個
1、改名,將本地分支名 v0.1_backup 改為和遠程分支名一樣的 v0.1 就可以了。神馬,同名的分支已存在?那你為什么不在已存在的那個分支上操作呢?
2、merge,比如上面說的和遠程分支同名的本地分支 v0.1 已存在時,可以先將 v0.1_backup 的修改 merge 到 v0.1 上,然后再在 v0.1 上 push 就可以了。雖然麻煩,但是這是標準操作(個人感覺)。
3、使用下面的命令也可以
git push origin v0.1_backup:v0.12019-7-14
轉載于:https://www.cnblogs.com/baiqiantao/p/11111287.html
總結
以上是生活随笔為你收集整理的-Git 使用技巧 总结 MD的全部內容,希望文章能夠幫你解決所遇到的問題。

- 上一篇: Oracle数据库常用的脚本命令(一)
- 下一篇: IOS和Andriod手机浏览器内核