Halaman manual git-diff
agak panjang, dan menjelaskan banyak kasus yang tampaknya tidak perlu bagi pemula. Sebagai contoh:
git diff origin/master
Halaman manual git-diff
agak panjang, dan menjelaskan banyak kasus yang tampaknya tidak perlu bagi pemula. Sebagai contoh:
git diff origin/master
Jawaban:
Mari kita lihat contoh lanjutan lanjutan dari sejarah git (dalam komit 1088261f di repositori git.git ):
diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int get_verbosely = 0;
int get_recover = 0;
+ prefix = setup_git_directory();
+
git_config(git_default_config, NULL);
while (arg < argc && argv[arg][0] == '-') {
Mari kita menganalisis garis patch ini demi baris.
Baris pertama
diff --git a / builtin-http-fetch.cb / http-fetch.cadalah header "git diff" dalam formulir
diff --git a/file1 b/file2
. Nama file a/
dan b/
sama kecuali kecuali mengubah nama / menyalin (seperti dalam kasus kami). The --git
adalah untuk berarti bahwa diff adalah di "git" format diff.Berikutnya adalah satu atau lebih baris tajuk yang diperluas. Tiga yang pertama
indeks kesamaan 95% ganti nama dari builtin-http-fetch.c ganti nama menjadi http-fetch.cberi tahu kami bahwa file diubah namanya dari
builtin-http-fetch.c
menjadi http-fetch.c
dan bahwa kedua file tersebut 95% identik (yang digunakan untuk mendeteksi nama ini). indeks f3e63d7..e8f44ba 100644memberi tahu kami tentang mode file yang diberikan (
100644
berarti bahwa itu file biasa dan bukan eg symlink, dan tidak memiliki bit izin yang dapat dieksekusi), dan tentang hash preimage yang dipersingkat (versi file sebelum diberikan perubahan) dan postimage ( versi file setelah perubahan). Baris ini digunakan oleh git am --3way
untuk mencoba melakukan penggabungan 3 arah jika tambalan tidak dapat diterapkan sendiri.Berikutnya adalah dua baris tajuk terpadu terpadu
--- a / builtin-http-fetch.c +++ b / http-fetch.cDibandingkan dengan
diff -U
hasil, ia tidak memiliki nama file dari-file-modifikasi-waktu atau ke-file-modifikasi setelah sumber (preimage) dan tujuan (postimage). Jika file dibuat sumbernya adalah /dev/null
; jika file dihapus, targetnya adalah /dev/null
. diff.mnemonicPrefix
variabel konfigurasi ke benar, di tempat a/
dan b/
prefiks dalam header dua-baris ini Anda dapat memiliki bukan c/
, i/
, w/
dan o/
sebagai awalan, masing-masing dengan apa yang Anda membandingkan; lihat git-config (1)Berikutnya datang satu atau lebih perbedaan pendapat; setiap bingkah menunjukkan satu area di mana file berbeda. Bakhil format terpadu dimulai dengan garis seperti
@@ -1,8 +1,9 @@atau
@@ -18,6 +19,8 @@ int cmd_http_fetch (int argc, const char ** argv, ...Itu dalam format
@@ from-file-range to-file-range @@ [header]
. Dari-file-range dalam bentuk -<start line>,<number of lines>
, dan ke-file-range adalah +<start line>,<number of lines>
. Garis awal dan jumlah garis mengacu pada posisi dan panjang bingkah di preimage dan postimage, masing-masing. Jika jumlah baris tidak ditampilkan itu berarti 0.
Header opsional menunjukkan fungsi C di mana setiap perubahan terjadi, jika itu adalah file C (seperti -p
opsi dalam GNU diff), atau yang setara, jika ada, untuk jenis file lainnya.
Berikutnya adalah deskripsi di mana file berbeda. Garis-garis yang umum untuk kedua file dimulai dengan karakter spasi. Garis-garis yang sebenarnya berbeda antara dua file memiliki salah satu karakter indikator berikut di kolom cetak kiri:
Jadi, misalnya, potongan pertama
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
berarti cmd_http_fetch
digantikan oleh main
, dan const char *prefix;
baris itu ditambahkan.
Dengan kata lain, sebelum perubahan, fragmen yang sesuai dari file 'builtin-http-fetch.c' saat itu tampak seperti ini:
#include "cache.h"
#include "walker.h"
int cmd_http_fetch(int argc, const char **argv, const char *prefix)
{
struct walker *walker;
int commits_on_stdin = 0;
int commits;
Setelah perubahan, fragmen file sekarang 'http-fetch.c' ini terlihat seperti ini:
#include "cache.h"
#include "walker.h"
int main(int argc, const char **argv)
{
const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
Mungkin ada
\ Tidak ada baris baru di akhir filebaris sekarang (tidak dalam contoh diff).
Seperti yang dikatakan Donal Fellows , yang terbaik adalah berlatih membaca perbedaan pada contoh kehidupan nyata, di mana Anda tahu apa yang telah Anda ubah.
Referensi:
git blame -C -C
, begitulah cara kerjanya; itu adalah keputusan desain Git. Format git diff hanya menunjukkan indeks kesamaan (atau perbedaan) dengan pengguna.
[header]
adalah yang terdekat sebelumnya seperti dengan awal fungsi yang mendahului sebongkah. Dalam kebanyakan kasus, baris ini menyertakan nama fungsi di mana bilangan diff berada. Ini dapat dikonfigurasi dengan diff
gitattribute diatur ke driver berbeda, dan driver berbeda termasuk xfuncname
variabel konfigurasi.
@@ -1,2 +3,4 @@
bagian dari diff
Bagian ini perlu waktu untuk saya mengerti, jadi saya telah membuat contoh minimal.
Formatnya pada dasarnya sama dengan diff -u
unified diff.
Misalnya:
diff -u <(seq 16) <(seq 16 | grep -Ev '^(2|3|14|15)$')
Di sini kami menghapus baris 2, 3, 14 dan 15. Output:
@@ -1,6 +1,4 @@
1
-2
-3
4
5
6
@@ -11,6 +9,4 @@
11
12
13
-14
-15
16
@@ -1,6 +1,4 @@
cara:
-1,6
berarti bahwa bagian dari file pertama ini dimulai pada baris 1 dan menunjukkan total 6 baris. Oleh karena itu menunjukkan garis 1 hingga 6.
1
2
3
4
5
6
-
berarti "tua", seperti yang biasa kita panggil diff -u old new
.
+1,4
berarti bahwa bagian dari file kedua ini dimulai pada baris 1 dan menunjukkan total 4 baris. Karenanya ia menunjukkan baris 1 hingga 4.
+
berarti "baru".
Kami hanya memiliki 4 baris, bukan 6 karena 2 baris telah dihapus! Cowok baru itu hanya:
1
4
5
6
@@ -11,6 +9,4 @@
untuk cowok kedua adalah analog:
pada file lama, kami memiliki 6 baris, mulai dari baris 11 dari file lama:
11
12
13
14
15
16
pada file baru, kami memiliki 4 baris, mulai dari baris 9 file baru:
11
12
13
16
Perhatikan bahwa baris 11
adalah baris ke-9 dari file baru karena kita telah menghapus 2 baris pada bingkah sebelumnya: 2 dan 3.
Header sebongkah
Bergantung pada versi git dan konfigurasi Anda, Anda juga bisa mendapatkan baris kode di sebelah @@
baris, misalnya func1() {
di:
@@ -4,7 +4,6 @@ func1() {
Ini juga bisa diperoleh dengan -p
bendera polos diff
.
Contoh: file lama:
func1() {
1;
2;
3;
4;
5;
6;
7;
8;
9;
}
Jika kita menghapus garis 6
, diff menunjukkan:
@@ -4,7 +4,6 @@ func1() {
3;
4;
5;
- 6;
7;
8;
9;
Perhatikan bahwa ini bukan garis yang benar untuk func1
: ia melewatkan garis 1
dan 2
.
Fitur luar biasa ini sering memberi tahu persis ke fungsi atau kelas mana masing-masing hunk milik, yang sangat berguna untuk menafsirkan diff.
Bagaimana algoritma untuk memilih header bekerja dengan tepat dibahas di: Di mana kutipan dari header git diff hunk berasal?
@@ -1,6 +1,4 @@
pls tidak membaca -1
sebagai minus one
atau +1
sebagai plus one
gantinya membaca ini sebagai line 1 to 6
di tua (pertama) file. Catatan di sini - implies "old"
bukan minus. BTW, terima kasih atas klarifikasi ... haash.
+1,4
mengatakan bahwa bagian ini sesuai dengan baris 1 hingga 4 dari file kedua ". Ini karena +1,4
dapat merujuk ke garis konteks non-kontingen. Sebaliknya, apa yang +1,4
sebenarnya " " maksud adalah bahwa " ada 4
garis (yaitu garis konteks) dalam 'versi' file ". Hal ini penting untuk memahami arti dari +
, -
, dan <whitespace>
pada awal garis, yang berlaku untuk interpretasi bakhil. Contoh yang lebih visual: youtube.com/watch?v=1tqMjJeyKpw
Inilah contoh sederhana.
diff --git a/file b/file
index 10ff2df..84d4fa2 100644
--- a/file
+++ b/file
@@ -1,5 +1,5 @@
line1
line2
-this line will be deleted
line4
line5
+this line is added
Berikut penjelasannya (lihat detailnya di sini ).
--git
bukan perintah, ini berarti versi git dari diff (bukan unix)a/ b/
direktori, itu tidak nyata. itu hanya kenyamanan ketika kita berurusan dengan file yang sama (dalam kasus saya a / ada di indeks dan b / ada di direktori kerja)10ff2df..84d4fa2
adalah gumpalan ID dari 2 file ini100644
adalah "mode bits," yang menunjukkan bahwa ini adalah file biasa (tidak dapat dieksekusi dan bukan tautan simbolik)--- a/file +++ b/file
tanda minus menunjukkan garis dalam a / versi tetapi hilang dari b / versi; dan tanda tambah menunjukkan baris-baris yang hilang pada / tetapi ada pada b / (dalam kasus saya --- berarti baris yang dihapus dan +++ berarti baris yang ditambahkan dalam b / dan ini file dalam direktori kerja)@@ -1,5 +1,5 @@
untuk memahami ini, lebih baik bekerja dengan file besar; jika Anda memiliki dua perubahan di tempat yang berbeda Anda akan mendapatkan dua entri seperti @@ -1,5 +1,5 @@
; misalkan Anda memiliki file line1 ... line100 dan dihapus line10 dan tambahkan line100 baru - Anda akan mendapatkan:@@ -7,7 +7,6 @@ line6 line7 line8 line9 -this line10 to be deleted line11 line12 line13 @@ -98,3 +97,4 @@ line97 line98 line99 line100 +this is new line100
644
) harus dibaca dalam oktal (nilai: 1, 2, 4 masing-masing izin eXecute, Tulis, dan Baca) dan sesuai dengan urutan tersebut untuk Pemilik (Pengguna), lalu Grup, lalu izin lainnya. Jadi singkatnya 644
akan berarti jika ditulis secara simbolis u=rw,og=r
, yang dapat dibaca oleh semua orang tetapi hanya dapat ditulis oleh pemilik. Digit lainnya di sebelah kiri menyandikan informasi lain, seperti jika itu adalah symlink, dll. Nilai dapat dilihat github.com/git/git/blob/… , 1 pertama di posisi ini adalah "file biasa".
Format output default (yang awalnya berasal dari program yang dikenal seolah- diff
olah Anda ingin mencari info lebih lanjut) dikenal sebagai "unified diff". Ini pada dasarnya mengandung 4 jenis garis:
+
,-
, danSaya menyarankan Anda berlatih membaca perbedaan antara dua versi file di mana Anda tahu persis apa yang Anda ubah. Seperti itu Anda akan mengenali apa yang sedang terjadi ketika Anda melihatnya.
Di mac saya:
info diff
lalu pilih: Output formats
-> Context
-> Unified format
-> Detailed Unified
:
Atau man online berbeda pada gnu mengikuti jalur yang sama ke bagian yang sama:
File: diff.info, Node: Detail Unified, Selanjutnya: Contoh Unified, Up: Unified Format
Penjelasan terperinci tentang Format Terpadu ..........................................
Format output terpadu dimulai dengan header dua baris, yang terlihat seperti ini:
--- FROM-FILE FROM-FILE-MODIFICATION-TIME +++ TO-FILE TO-FILE-MODIFICATION-TIME
Cap waktu tampak seperti `2002-02-21 23: 30: 39.942229878 -0800 'untuk menunjukkan tanggal, waktu dengan detik fraksional, dan zona waktu.
Anda dapat mengubah konten tajuk dengan opsi `--label = LABEL '; lihat * Catatan Nama Alternatif ::.
Berikutnya datang satu atau lebih perbedaan pendapat; setiap bingkah menunjukkan satu area di mana file berbeda. Bakhal format terpadu terlihat seperti ini:
@@ FROM-FILE-RANGE TO-FILE-RANGE @@ LINE-FROM-EITHER-FILE LINE-FROM-EITHER-FILE...
Garis-garis yang umum untuk kedua file dimulai dengan karakter spasi. Garis-garis yang sebenarnya berbeda antara dua file memiliki salah satu karakter indikator berikut di kolom cetak kiri:
`+ 'Baris ditambahkan di sini ke file pertama.
`- 'Baris dihapus di sini dari file pertama.
Tidak jelas dari pertanyaan Anda bagian mana dari diff yang Anda anggap membingungkan: sebenarnya diff, atau informasi header tambahan yang dicetak git. Untuk jaga-jaga, berikut ini ikhtisar singkat header.
Baris pertama adalah sesuatu seperti diff --git a/path/to/file b/path/to/file
- jelas itu hanya memberi tahu Anda untuk apa file bagian diff ini. Jika Anda mengatur variabel konfigurasi boolean diff.mnemonic prefix
, a
dan b
akan diubah menjadi huruf yang lebih deskriptif seperti c
dan w
(komit dan pohon kerja).
Berikutnya, ada "garis mode" - garis yang memberi Anda deskripsi tentang perubahan yang tidak melibatkan perubahan konten file. Ini termasuk file baru / dihapus, file berganti nama / disalin, dan perubahan izin.
Akhirnya, ada garis seperti index 789bd4..0afb621 100644
. Anda mungkin tidak akan pernah mempedulikannya, tetapi angka hex 6 digit tersebut adalah hash SHA1 disingkat dari gumpalan lama dan baru untuk file ini (gumpalan adalah objek git yang menyimpan data mentah seperti isi file). Dan tentu saja, 100644
ini adalah mode file - tiga digit terakhir jelas izin; tiga yang pertama memberikan informasi metadata file tambahan ( posting SO menggambarkan itu ).
Setelah itu, Anda beralih ke output unified diff standar (seperti klasik diff -U
). Ini dibagi menjadi bakhil - sebongkah adalah bagian dari file yang berisi perubahan dan konteksnya. Setiap potongan didahului oleh sepasang ---
dan +++
garis - garis yang menunjukkan file yang dimaksud, kemudian perbedaan aktual adalah (secara default) tiga baris konteks di kedua sisi -
dan +
garis-garis yang menunjukkan baris yang dihapus / ditambahkan.
index
saluran. Dikonfirmasi dengangit hash-object ./file