在上篇中,我們已經能基本使用git了,接下來繼續更深入的挖掘一下git。
更多的配置自定義資訊
除了前面講的使用者名稱和郵箱的配置,還可以自定義其他配置:
# 自定義你喜歡的編輯器,可選
git config --global core.editor vim
# 自定義差異工具,可選
git config --global merge.tool vimdiff
git config --global mergetool.prompt false
# 為git著色
git config --global color.ui true
還有一些配置,比如core.autocrlf,core.whitespace等等就點到為止,不做贅述。
忽略檔案 -- 使用.gitignore
git支援使用.gitignore檔案定義忽略規則,一行一個。
gitignore檔案只能忽略非版本庫的檔案,對於已經新增到版本庫的檔案,需要先刪除掉才能忽略。
所以,一般.gitignore檔案建議在建立專案的時候就加進來,這樣可以減少不必要的麻煩,不必把一些中間生成檔案新增到版本庫。
以Android為例子:
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Android Studio
.idea/
.gradle
/*/local.properties
/*/out
build
/*/*/production
*.iml
*.iws
*.ipr
*~
*.swp
兩個重要概念
git最基礎也是最重要的兩個概念:物件模型和版本跟蹤結構。
物件模型定義了git版本儲存的方式。
每一次提交git會根據內容生成一個SHA1值,作為物件名。版本跟蹤結構分為4個部分:工作區,暫存區,本地倉庫,遠端倉庫。
修改提交
難免在提交之後發現一些錯誤,希望能亡羊補牢補救一下,這就需要使用如下命令。
# 修改上次的提交
git commit --amend
# 合併本地所有未提交的提交, 在彈出的互動介面, 保留一行的pick,把其他每行提交的pick改為fixup或者squuash
# 其實從上面的操作上看,如果你想保留幾個提交,就保留幾個pick即可
git rebase -i origin/master
# 合併最後兩個提交, 在彈出的互動介面,操作同上
git rebase -i HEAD~2
簡單的修改提交可能是合理的,但是合併提交,就需要考慮到提交的目的,不建議把完全獨立的提交硬是合併在一起, 從工程上會降低版本管理的意義,同時增大了合併到其他分支出錯的可能性。
cherry-pick -- 分支之間的smart merge
前面講到了branch,它的使用場景下,有一種常見的操作,就是把某個commit也合併到另外一個分支B,怎麼做呢?
// 切換到分支B
git checkout B
// 把之前的commit使用cherry-pick命令到當前分支
git cherry-pick 5d1c8562cd3d6b902e7d1542940ba39a97179017
reset的藝術
git reset的藝術就在於它的幾個引數的使用。
當了解上面定義的版本庫,暫存區,工作區概念之後,reset的幾個引數的區別就非常好說明了,我畫了一張圖:
二分法定位問題 -- git bisect的使用
如果一個專案的提交非常對,面對一個不知道什麼時候出現的bug,git借用了二分法平均時間最快的思想,提供了git bisect命令。
// 開始查詢, 對應最後面的結束查詢
git bisect start
// 標記當前版本為錯誤
git bisect bad
// 標記5d1c8562cd3d6b902e為正確的版本
git bisect good 5d1c8562cd3d6b902e
// 現在git會自動選取bad和good的中間版本
// ...
// 我們能做的就是不斷的測試並標記這些中間版本時good還是bad,直到找到問題
// git bisect good 或者git bisect bad
// ...
// 結束查詢,回到開始查詢之前的狀態
git bisect reset
這行程式碼是誰加的 -- git blame助你火眼金睛
git blame命令可以檢視每個檔案的每一行的版本資訊,包括提交SHA,日期,作者:
git blame ./lesscode-core/src/main/java/com/jayfeng/lesscode/core/AdapterLess.java
結果:
406962f0 (Jay 2015-02-05 19:31:17 +0800 1) package com.jayfeng.lesscode.core;
406962f0 (Jay 2015-02-05 19:31:17 +0800 2)
406962f0 (Jay 2015-02-05 19:31:17 +0800 3) import android.content.Context;
8ee8388a (Jay 2015-05-23 18:20:40 +0800 4) import android.support.v4.app.Fragment;
8ee8388a (Jay 2015-05-23 18:20:40 +0800 5) import android.support.v4.app.FragmentManager;
8ee8388a (Jay 2015-05-23 18:20:40 +0800 6) import android.support.v4.app.FragmentPagerAdapter;
a03f8aa3 (Jay 2015-05-23 16:59:05 +0800 7) import android.support.v4.view.PagerAdapter;
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 8) import android.support.v7.widget.RecyclerView;
406962f0 (Jay 2015-02-05 19:31:17 +0800 9) import android.util.SparseArray;
406962f0 (Jay 2015-02-05 19:31:17 +0800 10) import android.view.LayoutInflater;
406962f0 (Jay 2015-02-05 19:31:17 +0800 11) import android.view.View;
406962f0 (Jay 2015-02-05 19:31:17 +0800 12) import android.view.ViewGroup;
406962f0 (Jay 2015-02-05 19:31:17 +0800 13) import android.widget.BaseAdapter;
406962f0 (Jay 2015-02-05 19:31:17 +0800 14)
406962f0 (Jay 2015-02-05 19:31:17 +0800 15) import java.util.List;
406962f0 (Jay 2015-02-05 19:31:17 +0800 16)
4719215f (think 2015-02-06 22:06:50 +0800 17) public class AdapterLess {
406962f0 (Jay 2015-02-05 19:31:17 +0800 18)
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 19) public static <T> RecyclerView.Adapter<RecycleViewHolder> $recycle(final Context context,
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 20) final List<T> list,
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 21) final int layoutId,
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 22) final RecycleCallBack recycleCallBack) {
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 23) RecyclerView.Adapter<RecycleViewHolder> result = new RecyclerView.Adapter<RecycleViewHolder>() {
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 24) @Override
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 25) public RecycleViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 26) View view = LayoutInflater.from(context)
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 27) .inflate(layoutId, viewGroup, false);
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 28) RecycleViewHolder recycleViewHolder = new RecycleViewHolder(view);
2cf7bb1c (Jay 2015-07-26 11:59:18 +0800 44) ... ...
小結
git作為小而美的工具,開創了一個版本控制的新時代。
學習git是一個循序漸進的過程,通過結合基本使用方法和實踐場景的練習,達到熟練使用的程度,可成!
同步釋出:http://www.jayfeng.com/2015/07/25/記一次小團隊Git實踐(下)/