Git 使用指南

git init

初始化html

git init

git clone

克隆git

git clone [遠端倉庫] [目標文件夾名稱(默認:遠端倉庫的名字)]

git log

查看歷史提交github

  • 當前分支
  • 按時間前後順序顯示到[校驗和]爲止
git log [校驗和(默認:最新提交的校驗和)]

選項:vim

  • --oneline:精簡至單行版本
  • --stat:增長文件修改信息
  • -p:忽略空格引發的不一樣
  • -w:忽略空格引發的不一樣
  • --all --graph:用分支圖顯示全部歷史提交
  • --author="[做者]":顯示做者包含[文本]的歷史提交
  • --grep="[文本]":顯示內容包含[文本]的歷史提交

但願選項--all --graph成爲命令git log的默認參數?segmentfault

在文件.bashrc中加入:bash

git() {
    if [ "$1" = "log" ]
    then
        command git log --all --graph "${@:2}";
    else
        command git "$@";
    fi;
}

Enabling git log parameters by defaultapp

git shortlog

查看歷史提交:按做者分類顯示less

git shortlog

git show

查看[校驗和]提交的全部信息ide

git show [校驗和(默認:最新提交的校驗和)]

查看附註標籤(Annotated Tag)的內容工具

git tag [標籤名]

選項同命令git log

git status

查看當前狀態

git status

git diff

查看還沒有加入暫存區的改動

git diff

git stash

Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.

常常有這樣的事情發生,當你正在進行項目中某一部分的工做,裏面的東西處於一個比較雜亂的狀態,而你想轉到其餘分支上進行一些工做。問題是,你不想提交進行了一半的工做,不然之後你沒法回到這個工做點。解決這個問題的辦法就是git stash命令。

保存工做區的更改到暫存,恢復工做區至上次提交。

git stash

查看全部暫存

git stash list

恢復暫存到工做區

git stash apply [暫存記錄(默認:最新暫存記錄)]

恢復暫存到工做區,同時刪除暫存記錄。

git stash pop [暫存記錄(默認:最新暫存記錄)]

git add

將文件從工做區添加到暫存區

git add [文件名1 文件名2 文件名3 ...]

將全部文件(文件.gitignore指示的除外)從工做區添加到暫存區

git add .

git rm

將文件從暫存區移回到工做區

git rm --cached [文件名1 文件名2 文件名3 ...]

git commit

將暫存區提交到本地倉庫

  • 會進入一個 vim 窗口,在此輸入提交信息。
  • 全部以#開頭的行都會被忽略。
  • 對於空行的問題無需糾結,由於 git 會忽略全部沒必要要的空行。
git commit

鍵入提交信息並提交

git commit -m [提交信息]

更新最近的提交(內容和信息)

git commit --amend

如修改了提交內容,建議先執行:

git add .

提交的本質是區塊鏈的節點,每一個節點存儲了上一個提交(父提交)的校驗和。父提交多是1個(一般),也多是2個(分支的合併提交)。

提交信息的書寫規範(Udacity

The goal is that each commit has a single focus. Each commit should record a single-unit change. Now this can be a bit subjective (which is totally fine), but each commit should make a change to just one aspect of the project.

Conversely, a commit shouldn't include unrelated changes - changes to the sidebar and rewording content in the footer. These two aren't related to each other and shouldn't be included in the same commit. Work on one change first, commit that, and then change the second one. That way, if it turns out that one change had a bug and you have to undo it, you don't have to undo the other change too.

The best way that I've found to think about what should be in a commit is to think, "What if all changes introduced in this commit were erased?". If a commit were erased, it should only remove one thing.

DO:

  • do keep the message short (less than 60-ish characters)
  • do explain what the commit does (not how or why!)

DO NOT:

  • do not explain why the changes are made (more on this below)
  • do not explain how the changes are made (that's what git log -p is for!)
  • do not use the word "and"

    • if you have to use "and", your commit message is probably doing too many changes - break the changes into separate commits
    • e.g. "make the background color pink and increase the size of the sidebar"

完整版文檔:Udacity Git Commit Message Style Guide

git tag

查看全部標籤

git tag

添加輕便標籤(Lightweight Tag)

git tag [標籤名] [校驗和(默認:最新提交的校驗和)]

添加附註標籤(Annotated Tag)

  • 會進入一個 vim 窗口,在此輸入標籤內容。
  • 全部以#開頭的行都會被忽略。對於空行的問題無需糾結,
  • 由於 git 會忽略全部沒必要要的空行。
git tag -a [標籤名] [校驗和(默認:最新提交的校驗和)]

鍵入附註標籤的內容並提交

git tag -a [標籤名] [校驗和(默認:最新提交的校驗和)] -m [附註標籤的內容]

刪除本地標籤

git tag -d [標籤名1 標籤名2 標籤名3 ...]

刪除指定遠端標籤

git push [遠端名] -d refs/tags/[標籤名]
git push [遠端名] :refs/tags/[標籤名]

推送全部本地標籤到遠端

git push [遠端名] --tag

從遠端拉取全部標籤到本地

git fetch [遠端名] --tag

在遠端惟一的狀況下,上述[遠端名]能夠省略。

標籤的本質是引用(ref),指向一個提交或一個分支。

git checkout

切換

git checkout [校驗和 / 標籤名 / 分支名]

建立新分支並切換

git checkout -b [分支名]

恢復工做區中的某個文件到上次提交的狀態

git checkout -- [文件名]

恢復工做區中的所有文件到上次提交的狀態

git checkout -- .

git branch

查看全部本地分支

git branch

查看全部遠端分支

git branch -r

新建分支

git branch [分支名] [校驗和(默認:最新提交的校驗和)]

刪除分支

git branch -d [分支名1 分支名2 分支名3 ...]

刪除分支的前提條件是:

  • 該分支不是當前分支。
  • 該分支上的最新提交已經合併到另外一分支上(如需忽略本條件,請使用-D選項。警告:還沒有合併的全部提交將會所有丟失!)。

分支的本質是引用,指向一個提交。Git 將分支理解爲從首個提交到指向提交的序列

git merge

[源分支]合併到當前分支,一般有兩種狀況:

  • [源分支]是當前分支的更新:直接移動當前分支的 ref。
  • 建立[源分支]後,又當前分支上新建了提交:建立一個合併提交,將[源分支]和當前分支的 ref 指向這個合併提交。
git merge [源分支]

合併操做操做會由於衝突(conflict)而停止,條件是:參與合併的兩個分支上,各存在一個提交,它們修改了同一個行範圍。

如需撤銷合併操做,請使用命令git merge --abort

衝突的處理方法(Udacity

Merge Conflict Output Explained

The output that shows in the Terminal is:

$ git merge heading-update
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Notice that right after the git merge heading-update command, it tries merging the file that was changed on both branches (index.html), but that there was a conflict. Also, notice that it tells you what happened - "Automatic merge failed; fix conflicts and then commit the result".

Remember our good friend git status? Well he'll come in really handy when working with merge conflicts.

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file> ..." to mark resolution)

        both modified:   index.html

The git status output tells us to that the merge conflict is inside index.html. So check out that file in your code editor!

圖片描述

Merge Conflict Indicators Explanation

  • <<<<<<< HEAD everything below this line (until the next indicator) shows you what's on the current branch
  • ||||||| merged common ancestors everything below this line (until the next indicator) shows you what the original lines were
  • > > > > > > > heading-update is the ending indicator of what's on the branch that's being merged in (in this case, the heading-update branch)

Resolving A Merge Conflict

Git is using the merge conflict indicators to show you what lines caused the merge conflict on the two different branches as well as what the original line used to have. So to resolve a merge conflict, you need to:

  • choose which line(s) to keep
  • remove all lines with indicators

For some reason, I'm not happy with the word "Crusade" right now, but "Quest" isn't all that exciting either. How about "Adventurous Quest" as a heading?!?

Commit Merge Conflict

Once you've removed all lines with merge conflict indicators and have selected what heading you want to use, just save the file, add it to the staging index, and commit it! Just like with a regular merge, this will pop open your code editor for you to supply a commit message. Just like before, it's common to use the provided merge commit message, so after the editor opens, just close it to use the provided commit message.

And that's it! Merge conflicts really aren't all that challenging once you understand what the merge conflict indicators are showing you.

If a merge conflict occurs in a file and you edit the file, save it, stage it, and commit it but forget to remove the merge conflict indicators, Git will commit the lines with the merge conflict indicators, because they're just regular characters.

git revert

git revert [校驗和]

[校驗和]提交的前一個提交爲PREVIOUS,修改的行範圍是range

該命令的做用是回滾range範圍內的修改,將會產生一個新的提交

回滾操做操做會由於衝突而停止,條件是:若是range範圍內的某一部分在[校驗和]提交的某個後續提交中被修改。

如需撤銷回歸操做,請使用命令git revert --abort

衝突的處理方法與命令git merge相同。

git reset

git reset [校驗和]

該命令的做用是回到[校驗和]提交的狀態,即撤銷[校驗和]提交的後續提交的全部修改modification

選項:

  • --mixed:將modification移入工做區(默認)
  • --soft:將modification移入暫存區
  • --hard:刪除modification

執行命令git reset以後,[校驗和]提交的後續提交未被刪除。

能夠經過下列命令查看這些不屬於任何分支的提交

  • git relog
  • git fsck --unreachable --no-reflog

(具體使用方法詳見後文。)

能夠經過切換到提交、新建分支、合併到現有分支的方法恢復這些提交。

相對引用(Udacity

Relative Commit References

You already know that you can reference commits by their SHA, by tags, branches, and the special HEAD pointer. Sometimes that's not enough, though. There will be times when you'll want to reference a commit relative to another commit. For example, there will be times where you'll want to tell Git about the commit that's one before the current commit...or two before the current commit. There are special characters called "Ancestry References" that we can use to tell Git about these relative references. Those characters are:

  • ^ – indicates the parent commit
  • ~ – indicates the first parent commit

Here's how we can refer to previous commits:

  • the parent commit – the following indicate the parent commit of the current commit

    • HEAD^
    • HEAD~
    • HEAD~1
  • the grandparent commit – the following indicate the grandparent commit of the current commit

    • HEAD^^
    • HEAD~2
  • the great-grandparent commit – the following indicate the great-grandparent commit of the current commit

    • HEAD^^^
    • HEAD~3

The main difference between the ^ and the ~ is when a commit is created from a merge. A merge commit has two parents. With a merge commit, the ^ reference is used to indicate the first parent of the commit while ^2 indicates the second parent.

  • The first parent is the branch you were on when you ran git merge
  • The second parent is the branch that was merged in.

git remote

查看全部遠端倉庫的 URL

git remote -v

關聯到遠端倉庫:[遠端倉庫的別名]一般被設爲origin

git remote add [遠端倉庫的別名] [遠端倉庫的URL]

取消與遠端倉庫的關聯

git remote remove [遠端倉庫的別名]

重命名遠端倉庫

git remote rename [舊名稱] [新名稱]

git push

將本地分支推送到遠端

git push [遠端名] [本地分支] [遠端分支]

省略[遠端分支]的情形:將[本地分支]推送到同名的遠程分支,若是該遠程分支不存在,則會被新建。

git push [遠端名] [本地分支]

能夠爲該命令添加-u參數,表示在推送的同時,設定遠端名中的遠端分支[本地分支]的 upstream branch。一樣,同名的遠端分支能夠省略。

git push -u [遠端名] [本地分支] [遠端分支]
git push -u [遠端名] [本地分支]

在執行上述命令後,就能夠切換到相應本地分支(命令git checkout)並直接使用命令git push了。

git push

若是出現各類緣由致使命令git push不能成功執行(例如:刪除並重建本地分支、修改本地分支上的歷史提交),可使用選項-f進行覆蓋(強行)推送。不要在多人合做的遠端分支中使用!!!緣由參見:

git push -f

刪除遠端分支

git push [遠端名] -d [遠端分支]
git push [遠端名] :[遠端分支]

git pull

將遠端分支拉取到本地:取回遠程主機某個分支的更新,再與本地的指定分支合併

git pull [遠端名] [遠端分支]:[本地分支]

在知足下列條件的前提下,能夠直接使用命令git pull

  • 已使用命令git checkout將該對應的本地分支切換爲當前分支。
  • 該分支的 upstream branch 已設置。有兩種方法:

    • 執行命令git branch --set-upstream-to=[遠端名]/[遠端分支] [本地分支]
    • 藉助帶選項-u的命令git push
git pull

git fetch

將遠端分支拉取到本地:取回遠程主機某個分支的更新,可是不與本地分支合併

git fetch [遠端名] [遠端分支]:[本地分支]

在知足下列條件的前提下,能夠直接使用命令git fetch

  • 已使用git checkout將該對應的本地分支切換爲當前分支。
  • 該分支的 upstream branch 已設置。有兩種方法:

    • 命令git branch --set-upstream-to=[遠端名]/[遠端分支] [本地分支]
    • 藉助git push命令的選項-u
git fetch

區別於命令git pull

  • 命令git fetch讓用戶決定怎樣合併遠端分支和本地分支。
  • 命令git pull自動進行分支合併,在某些狀況下可能沒法成功執行。

problem

本地分支和遠端分支被同時更新。

更新前:

master
                                    |
remote     a -- 3 -- d -- f -- e -- 7

============================================================

                              origin/master
                                    |
local      a -- 3 -- d -- f -- e -- 7
                                    |
                                  master

更新後:

master
                                          |
remote      a -- 3 -- d -- f -- e -- 7 -- 8

============================================================

                               origin/master
                                     |
local       a -- 3 -- d -- f -- e -- 7 -- b
                                          |
                                        master

Solution

首先先使用命令git fetch,獲取遠端分支更新。

master
                                          |
remote      a -- 3 -- d -- f -- e -- 7 -- 8

============================================================

                                    origin/master
                                          |
                                          8
                                        /
local       a -- 3 -- d -- f -- e -- 7 -- b
                                          |
                                        master

再使用命令git merge origin/master,將遠端分支合併到本地分支。

master
                                          |
remote      a -- 3 -- d -- f -- e -- 7 -- 8

============================================================

                                    origin/master
                                          |
                                          8
                                        /   \
local       a -- 3 -- d -- f -- e -- 7 -- b -- 4
                                               |
                                             master

最後使用命令git push,推送本地分支到遠端分支。

master
                                               |
                                          8    |
                                        /   \  |
remote      a -- 3 -- d -- f -- e -- 7 -- 8 -- 4

============================================================

                                         origin/master
                                               |
                                          8    |
                                        /   \  |
local       a -- 3 -- d -- f -- e -- 7 -- b -- 4
                                               |
                                             master

git rebase

將當前分支的修改應用到目標分支,步驟是:

  1. 找出同時位於兩個分支最新的提交最新提交(最新公共提交)。
  2. 將當前分支上最新公共提交後的全部提交,移動到目標分支後。
  3. 將當前分支指向最新提交。
git rebase [目標分支]

參考資料:

[校驗和]後的提交進行交互式修改(vim)。

git rebase -i [校驗和]

參考資料:

停止上述操做

git rebase --abort
Do not rebase commits that exist outside your repository.

If you follow that guideline, you’ll be fine. If you don’t, people will hate you, and you’ll be scorned by friends and family.

不要對在你的倉庫外有副本的分支執行變基。

若是你遵循這條金科玉律,就不會出差錯。 不然,人民羣衆會仇恨你,你的朋友和家人也會嘲笑你,唾棄你。

其餘

參考資料:https://www.worldhello.net/go...

操做記錄

查看90天內的操做記錄

git reflog

當即清除全部操做記錄(不推薦)

git reflog expire --expire=now --all

查看沒法顯示的對象

查看沒法顯示(unreachable)的對象,包括但不限於:

  • 暫存區操做時引入的臨時對象(以unreachable blob開頭)
  • 不在分支上的提交(以unreachable commit開頭)
git fsck --unreachable --no-reflog

清除對象

清除對象,一般是暫存區操做時引入的臨時對象。操做記錄中的對象不在清理範圍。

git prune

優化倉庫

優化倉庫

git gc
相關文章
相關標籤/搜索