Xem lịch sử thay đổi của tệp bằng cách sử dụng phiên bản Git


3090

Làm cách nào tôi có thể xem lịch sử thay đổi của một tệp riêng lẻ trong Git, chi tiết đầy đủ với những gì đã thay đổi?

Tôi đã có được như:

git log -- [filename]

trong đó hiển thị cho tôi lịch sử cam kết của tệp, nhưng làm thế nào để tôi nhận được nội dung của mỗi tệp thay đổi?

Tôi đang cố gắng thực hiện chuyển đổi từ MS SourceSafe và điều đó từng đơn giản right-clickshow history.


41
Các liên kết trên không còn hiệu lực. Liên kết này đang hoạt động ngày hôm nay: Sách cộng đồng Git
chris

1
Liên kết ở trên (được đăng bởi Chris) không còn hợp lệ. Liên kết này đang hoạt động ngày hôm nay: git-scm.com/book/en/v2
Cog

Câu trả lời:


2370

Đối với điều này tôi sẽ sử dụng:

gitk [filename]

hoặc để theo tên tập tin trước đổi tên

gitk --follow [filename]

28
Nhưng tôi thậm chí còn có một công cụ kết hợp ở trên với 'git đổ lỗi' cho phép tôi duyệt nguồn của tệp khi nó thay đổi theo thời gian ...
Egon Willighagen

26
Thật không may, điều này không theo lịch sử của các đổi tên tập tin trong quá khứ.
Dan Mould

146
Tôi cũng đang tìm kiếm lịch sử của các tập tin đã được đổi tên trước đó và tìm thấy chủ đề này đầu tiên. Giải pháp là sử dụng "git log --follow <filename>" như Phil đã chỉ ra ở đây .
Florian Gutmann

115
Tác giả đã tìm kiếm một công cụ dòng lệnh. Mặc dù gitk đi kèm với GIT, nhưng đây không phải là ứng dụng dòng lệnh hay GUI đặc biệt tốt.
mikemaccana

72
Có phải anh ta đang tìm kiếm một công cụ dòng lệnh? "Nhấp chuột phải -> hiển thị lịch sử" chắc chắn không ngụ ý nó.
hdgarrood

2235

Bạn có thể dùng

git log -p filename

để cho git tạo các bản vá cho mỗi mục nhật ký.

Xem

git help log

để có thêm tùy chọn - nó thực sự có thể làm rất nhiều điều hay :) Để chỉ nhận khác biệt cho một cam kết cụ thể, bạn có thể

git show HEAD 

hoặc bất kỳ sửa đổi nào khác bằng định danh. Hoặc dùng

gitk

để duyệt các thay đổi trực quan.


8
git show HEAD hiển thị tất cả các tệp, bạn có biết cách theo dõi một tệp riêng lẻ (như Richard đã yêu cầu) không?
Jonas Byström

5
bạn sử dụng: git show <revision> - tên tệp, sẽ hiển thị các khác biệt cho sửa đổi đó, trong trường hợp tồn tại một.
Marcos Oliveira

4
--stat cũng hữu ích. Bạn có thể sử dụng nó cùng với -p.
Raffi Khatchadourian

5
Điều đó thật tuyệt. gitk không hoạt động tốt khi chỉ định các đường dẫn không còn tồn tại nữa. Tôi đã sử dụng git log -p - đường dẫn.
Paulo Casaretto

6
Plus gitk trông giống như nó được xây dựng bởi quái vật boogie. Đây là một câu trả lời tuyệt vời và phù hợp nhất với câu hỏi ban đầu.
ghayes

1497

git log --follow -p -- path-to-file

Điều này sẽ hiển thị toàn bộ lịch sử của tệp (bao gồm cả lịch sử ngoài tên và với các khác biệt cho mỗi thay đổi).

Nói cách khác, nếu tệp được đặt tên barmột lần foo, thì git log -p bar(không có --followtùy chọn) sẽ chỉ hiển thị lịch sử của tệp cho đến khi được đổi tên - nó sẽ không hiển thị lịch sử của tệp khi được gọi là foo. Việc sử dụng git log --follow -p barsẽ hiển thị toàn bộ lịch sử của tệp, bao gồm mọi thay đổi đối với tệp khi được gọi là foo. Các -ptùy chọn đảm bảo rằng diffs được bao gồm cho mỗi thay đổi.


18
--stat cũng hữu ích. Bạn có thể sử dụng nó cùng với -p.
Raffi Khatchadourian

23
Tôi đồng ý đây là câu trả lời THỰC SỰ. (1.) --followđảm bảo rằng bạn thấy đổi tên tệp (2.) -pđảm bảo rằng bạn thấy cách tệp được thay đổi (3.) đó chỉ là dòng lệnh.
Trevor Boyd Smith

3
@NHDaly Tôi nhận thấy rằng --đã được thêm, nhưng tôi không biết tại sao điều này làm cho nó tốt nhất? Nó là cái gì vậy?
Stewohn

40
@Benjohn --Tùy chọn cho Git biết rằng nó đã đạt đến cuối của các tùy chọn và rằng bất kỳ điều gì tiếp theo --nên được coi là một đối số. Đối với git logđiều này chỉ làm cho bất kỳ sự khác biệt nếu bạn có một tên đường dẫn bắt đầu bằng một dấu gạch ngang . Giả sử bạn muốn biết lịch sử của một tệp có tên không may "--follow":git log --follow -p -- --follow
Dan Mould

10
@Benjohn: Thông thường, --nó rất hữu ích vì nó cũng có thể bảo vệ chống lại bất kỳ revisiontên nào khớp với tên tệp bạn đã nhập, điều này thực sự có thể đáng sợ. Ví dụ: Nếu bạn có cả nhánh và tệp có tên foo, git log -p foosẽ hiển thị lịch sử nhật ký git foo, chứ không phải lịch sử cho tệp foo . Nhưng @DanMoulding đã đúng vì --followlệnh chỉ lấy một tên tệp duy nhất làm đối số của nó, nên điều này ít cần thiết hơn vì nó không thể là a revision. Tôi chỉ học được rằng. Có lẽ bạn đã đúng khi để nó ra khỏi câu trả lời của bạn sau đó; Tôi không chắc.
NHDaly

172

Nếu bạn thích ở lại dựa trên văn bản, bạn có thể muốn sử dụng tig .

Cài đặt nhanh:

  • apt-get :# apt-get install tig
  • Homebrew (OS X) :$ brew install tig

Sử dụng nó để xem lịch sử trên một tệp duy nhất: tig [filename]
Hoặc duyệt lịch sử repo chi tiết:tig

Tương tự gitknhưng dựa trên văn bản. Hỗ trợ màu sắc trong thiết bị đầu cuối!


23
Công cụ dựa trên văn bản tuyệt vời, câu trả lời tuyệt vời. Tôi bối rối khi thấy các phụ thuộc cho cài đặt gitk trên máy chủ không đầu của tôi. Sẽ nâng cấp lại A +++
Tom McKenzie

Bạn cũng có thể xem các tệp cụ thể bằng tig, tức làtig -- path/to/specific/file
gloriphobia

110

git whatchanged -p filenamecũng tương đương với git log -p filenametrong trường hợp này.

Bạn cũng có thể thấy khi một dòng mã cụ thể bên trong một tệp được thay đổi với git blame filename. Điều này sẽ in ra một id cam kết ngắn, tác giả, dấu thời gian và dòng mã hoàn chỉnh cho mỗi dòng trong tệp. Điều này rất hữu ích sau khi bạn tìm thấy một lỗi và bạn muốn biết khi nào nó được giới thiệu (hoặc đó là lỗi của ai).


4
+1, nhưng filenamekhông phải là tùy chọn trong lệnh git blame filename.
rockXrock

7
"Người dùng mới được khuyến khích sử dụng git-log thay thế. (...) Lệnh được giữ chủ yếu vì lý do lịch sử;"
ciastek

105

Người dùng SourceTree

Nếu bạn sử dụng SourceTree để trực quan hóa kho lưu trữ của mình (nó miễn phí và khá tốt), bạn có thể nhấp chuột phải vào một tệp và chọn Nhật ký đã chọn

nhập mô tả hình ảnh ở đây

Màn hình (bên dưới) thân thiện hơn nhiều so với gitk và hầu hết các tùy chọn khác được liệt kê. Thật không may (tại thời điểm này) không có cách nào dễ dàng để khởi chạy chế độ xem này từ dòng lệnh - CLI của SourceTree hiện chỉ mở repos.

nhập mô tả hình ảnh ở đây


1
Tôi đặc biệt thích tùy chọn "Theo dõi các tệp đã đổi tên", cho phép bạn xem liệu một tệp đã được đổi tên hoặc di chuyển.
Chris

nhưng trừ khi tôi nhầm (xin vui lòng cho tôi biết!), người ta chỉ có thể so sánh hai phiên bản tại một thời điểm trong gui? Có khách hàng nào có giao diện thanh lịch để phân biệt nhiều phiên bản khác nhau cùng một lúc không? Có thể với chế độ xem thu nhỏ như trong Văn bản cao siêu? Điều đó sẽ thực sự hữu ích tôi nghĩ.
Sam Lewallen

@SamLewallen Nếu tôi hiểu chính xác bạn muốn so sánh ba cam kết khác nhau? Điều này nghe có vẻ giống như hợp nhất ba chiều (của tôi, của bạn, cơ sở) - thông thường chiến lược này được sử dụng để giải quyết xung đột hợp nhất không nhất thiết phải so sánh ba cam kết tùy ý. Có nhiều công cụ hỗ trợ hợp nhất ba cách stackoverflow.com/questions/10998728/, nhưng mẹo là cho các công cụ này các bản sửa đổi cụ thể git yet.com/inter liền / 2009/02/27 /
Fox Fox

Cảm ơn Mark Fox, đó là những gì tôi muốn nói. Bạn có biết bất kỳ ứng dụng nào sẽ làm điều đó không?
Sam Lewallen

1
@ MarnenLaibow-Koser Tôi không thể nhớ tại sao tôi cần SHA tại thời điểm đó. À
AechoLiu

63

Để hiển thị bản sửa đổi và tác giả đã sửa đổi lần cuối mỗi dòng của tệp:

git blame filename

hoặc nếu bạn muốn sử dụng GUI đổ lỗi mạnh mẽ:

git gui blame filename

49

Tóm tắt các câu trả lời khác sau khi đọc qua chúng và chơi một chút:

Lệnh dòng lệnh thông thường sẽ là

git log --follow --all -p dir/file.c

Nhưng bạn cũng có thể sử dụng gitk (gui) hoặc tig (text-ui) để đưa ra những cách nhìn dễ hiểu hơn cho con người.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

Trong debian / ubfox, lệnh cài đặt cho các công cụ đáng yêu này đúng như mong đợi:

sudo apt-get install gitk tig

Và tôi hiện đang sử dụng:

alias gdf='gitk --follow --all -p'

để tôi có thể chỉ cần gõ gdf dirđể có được một lịch sử tập trung của tất cả mọi thứ trong thư mục con dir.


2
Tôi nghĩ rằng đây là một câu trả lời tuyệt vời. Có thể bạn sẽ không được bình chọn vì bạn trả lời các cách khác (IMHO tốt hơn) để xem các thay đổi tức là thông qua gitk và tig ngoài git.
PopcornKing

Chỉ cần thêm vào để trả lời. Xác định vị trí đường dẫn (trong không gian git, tối đa tồn tại trong kho lưu trữ). Sau đó sử dụng lệnh được nêu ở trên "git log --follow --all -p <folder_path / file_path>". Có thể có trường hợp, filde / thư mục đã bị xóa trong lịch sử, do đó xác định vị trí đường dẫn tối đa tồn tại và cố gắng tìm nạp lịch sử của nó. làm !
ký sinh

2
--alldành cho tất cả các chi nhánh, phần còn lại được giải thích trong câu trả lời của @ Dan
cregox 18/03/2017

1
Ôi trời, sau một thời gian dài tìm kiếm giải pháp tốt để theo dõi tập tin ngoài việc đổi tên, cuối cùng, tôi đã tìm thấy nó ở đây. Hoạt động như quyến rũ! Cảm ơn!
xZero

25

Thêm bí danh này vào .gitconfig của bạn:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

Và sử dụng lệnh như thế này:

> git lg
> git lg -- filename

Đầu ra sẽ trông gần giống hệt như đầu ra gitk. Thưởng thức.


Sau khi tôi chạy phím tắt lg đó, tôi nói (và tôi trích dẫn) "Đẹp!". Tuy nhiên, lưu ý rằng "\ n" sau "--graph" là một lỗi.
jmbeck

3
Cũng có thể được sử dụng git lg -p filename- nó trả về một khác biệt đẹp của tập tin tìm kiếm.
Egel

22

Gần đây tôi phát hiện ra tigvà thấy nó rất hữu ích. Có một số trường hợp tôi muốn nó làm A hoặc B nhưng hầu hết thời gian nó khá gọn gàng.

Đối với trường hợp của bạn, tig <filename>có thể là những gì bạn đang tìm kiếm.

http://jonas.nitro.dk/tig/


trên centos yum cài đặt tig
zzapper

18

Bạn có thể sử dụng vscode với GitLens , đây là một công cụ rất mạnh. Sau khi cài đặt GitLens, hãy chuyển đến tab GitLens, chọn FILE HISTORYvà bạn có thể duyệt nó.

nhập mô tả hình ảnh ở đây


15

Tôi đã viết git-phát lại cho mục đích chính xác này

pip install git-playback
git playback [filename]

Điều này có lợi ích của cả việc hiển thị kết quả trong dòng lệnh (như git log -p) đồng thời cho phép bạn thực hiện từng bước cam kết bằng các phím mũi tên (như gitk).


13

Hoặc là:

gitx -- <path/to/filename>

nếu bạn đang sử dụng gitx


1
Đối với một số lý do gitx của tôi mở ra trống.
IgorGanapolsky

@IgorGanapolsky bạn phải chắc chắn rằng bạn đang ở gốc của kho git của bạn
zdsbs

10

Bạn cũng có thể thử điều này liệt kê các cam kết đã thay đổi một phần cụ thể của tệp (Được triển khai trong Git 1.8.4).

Kết quả trả về sẽ là danh sách các cam kết đã sửa đổi phần cụ thể này. Chỉ huy :

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

trong đó UpperLimit là start_line_number và LowerLimit là end_line_number của tệp.

Thêm chi tiết tại https://www.techpurohit.com/list-some-usiously-git-commands


9

Nếu bạn muốn xem toàn bộ lịch sử của một tập tin, bao gồm cả trên tất cả các khác chi nhánh sử dụng:

gitk --all <filename>

7

Với Tiện ích mở rộng Git tuyệt vời , bạn đi đến một điểm trong lịch sử nơi tệp vẫn tồn tại (nếu nó đã bị xóa, nếu không, hãy chuyển đến CHÍNH), chuyển sang File treetab, nhấp chuột phải vào tệp và chọn File history.

Theo mặc định, nó theo tệp thông qua các đổi tên và Blametab cho phép xem tên tại một phiên bản nhất định.

Nó có một số vấn đề nhỏ, như hiển thị fatal: Not a valid object nametrong Viewtab khi nhấp vào sửa đổi xóa, nhưng tôi có thể sống với điều đó. :-)


Đáng lưu ý rằng đây chỉ là Windows.
Evan Hahn

3
@EvanHahn không chính xác, thông qua mono người ta có thể sử dụng GitExtension cũng trên Linux, chúng tôi sử dụng nó trên Ubuntu và khá hạnh phúc. xem git-extensions-documentation.readthedocs.org/en/latest/ triệt
Shmil Con mèo

7

Nếu bạn đang sử dụng GUI git (trên Windows) trong menu Kho lưu trữ, bạn có thể sử dụng "Trực quan hóa Lịch sử của chủ nhân". Đánh dấu một cam kết ở khung trên cùng và một tệp ở phía dưới bên phải và bạn sẽ thấy khác biệt cho cam kết đó ở phía dưới bên trái.


Làm thế nào để trả lời câu hỏi này?
jmbeck

3
Chà, OP đã không chỉ định dòng lệnh và chuyển từ SourceSafe (là GUI) có vẻ như có liên quan để chỉ ra rằng bạn có thể làm khá nhiều điều tương tự như bạn có thể làm trong VSS trong GUI Git trên Windows.
cori

6

SmartGit :

  1. Trong menu cho phép hiển thị các tệp không thay đổi: Xem / Hiển thị các tệp không thay đổi
  2. Nhấp chuột phải vào tệp và chọn 'Nhật ký' hoặc nhấn 'Ctrl-L'

4

Câu trả lời tôi đang tìm kiếm không có trong chuỗi này là để xem các thay đổi trong các tệp mà tôi đã dàn dựng cho cam kết. I E

git diff --cached

1
Nếu bạn muốn bao gồm các thay đổi cục bộ (chưa được xử lý), tôi thường chạy git diff origin/masterđể hiển thị sự khác biệt hoàn toàn giữa chi nhánh địa phương của bạn và chi nhánh chính (có thể được cập nhật từ xa thông qua git fetch)
ghayes

4

Nếu bạn sử dụng TortoiseGit, bạn sẽ có thể nhấp chuột phải vào tệp và làm TortoiseGit --> Show Log. Trong cửa sổ bật lên, đảm bảo:

  • ' Show Whole Project' Tùy chọn không được chọn.

  • ' All Branches' Tùy chọn sẽ được kiểm tra.


TortoiseGit (và cả Git Eclipse) bằng cách nào đó bỏ lỡ các phiên bản của tệp đã chọn, đừng tin vào điều đó!
Noam Manos

@NoamManos, tôi chưa gặp phải vấn đề đó, vì vậy tôi không thể xác minh xem tuyên bố của bạn có đúng không.
dùng3885927

Lỗi của tôi, nó chỉ xảy ra trong Eclipse, nhưng trong TortoiseGit, bạn có thể thấy tất cả các phiên bản của tệp nếu bỏ chọn "hiển thị tất cả dự án" + kiểm tra "tất cả các nhánh" (trong trường hợp tệp được cam kết trên nhánh khác, trước khi nó được hợp nhất vào chính chi nhánh). Tôi sẽ cập nhật câu trả lời của bạn.
Noam Manos

3

git diff -U <filename> cung cấp cho bạn một khác biệt thống nhất.

Nó nên được tô màu đỏ và xanh lá cây. Nếu không, hãy chạy: git config color.ui autođầu tiên.


2

Nếu bạn đang sử dụng nhật thực với plugin git, nó có chế độ xem so sánh tuyệt vời với lịch sử. Nhấp chuột phải vào tệp và chọn "so sánh với" => "history"


Điều đó sẽ không cho phép bạn tìm một tập tin bị xóa tuy nhiên.
avgvstvs

So sánh hai phiên bản của một tệp khác với Xem lịch sử thay đổi của tệp
golimar

0

Tôi có lẽ là về nơi OP đã bắt đầu khi nó bắt đầu, tìm kiếm thứ gì đó đơn giản cho phép tôi sử dụng git Difftool với vimdiff để xem xét các thay đổi đối với các tệp trong repo của tôi bắt đầu từ một cam kết cụ thể. Tôi không hài lòng với câu trả lời mà tôi đang tìm kiếm, vì vậy tôi đã ném tập lệnh git inc remental rep orter (gitincrep) này cùng nhau và nó rất hữu ích với tôi:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Được gọi là không có đối số, điều này sẽ bắt đầu từ đầu lịch sử repo, nếu không nó sẽ bắt đầu với bất kỳ hàm băm viết tắt nào bạn cung cấp và tiếp tục đến hiện tại - bạn có thể ctrl-C bất cứ lúc nào để thoát. Bất kỳ đối số nào sau lần đầu tiên sẽ giới hạn các báo cáo khác biệt chỉ bao gồm các tệp được liệt kê trong số các đối số đó (mà tôi nghĩ là những gì OP muốn và tôi khuyên bạn nên sử dụng cho tất cả các dự án nhỏ). Nếu bạn đang kiểm tra các thay đổi đối với các tệp cụ thể muốn bắt đầu lại từ đầu, bạn sẽ cần cung cấp một chuỗi trống cho arg1. Nếu bạn không phải là người dùng vim, bạn có thể thay thế vimdiff bằng công cụ tìm khác biệt yêu thích của bạn.

Hành vi là đưa ra các nhận xét cam kết khi tìm thấy các thay đổi có liên quan và bắt đầu cung cấp các vimdiff chạy cho mỗi tệp đã thay đổi (đó là hành vi git differftool , nhưng nó hoạt động ở đây).

Cách tiếp cận này có thể khá ngây thơ, nhưng xem qua rất nhiều giải pháp ở đây và tại một bài đăng liên quan, nhiều người tham gia cài đặt các công cụ mới trên hệ thống mà tôi không có quyền truy cập quản trị viên, với các giao diện có đường cong học tập của riêng họ. Kịch bản trên đã làm những gì tôi muốn mà không phải đối phó với bất kỳ điều đó. Tôi sẽ xem xét nhiều đề xuất tuyệt vời ở đây khi tôi cần thứ gì đó tinh vi hơn - nhưng tôi nghĩ rằng điều này đáp ứng trực tiếp với OP.


0

Tôi đã tìm thấy một giải pháp rất đơn giản để nhanh chóng tìm thấy lịch sử của tập tin.

  1. Thực hiện một thay đổi ngẫu nhiên trong tập tin
  2. Nó sẽ hiển thị dưới dạng những thay đổi không được cam kết trên tài liệu của bạn
  3. Nhấp chuột phải vào tệp và chọn 'Đăng nhập được chọn'

nhập mô tả hình ảnh ở đây

Nó sẽ hiển thị lịch sử của tất cả các cam kết.


GUI này đến từ đâu?
colidyre

Giao diện người dùng. Cảm ơn
savvyBrar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.