Git: Git brune


Các khóa học qua video dành cho Hội viên:
Python Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript
<76K/month for all. Đăng ký Hội viên
Đăng ký nhận thông báo về những video mới nhất

Lệnh git prune là một tiện ích vệ sinh nội bộ mà dọn dẹp không thể truy cập hoặc "mồ côi" Git đối tượng. Các đối tượng không thể truy cập là những đối tượng không thể truy cập bởi bất kỳ ref nào. Bất kỳ cam kết nào không thể được truy cập thông qua một chi nhánh hoặc thẻ được coi là không thể truy cập. git prunethường không được thực hiện trực tiếp. Prune được coi là lệnh thu gom rác và là lệnh con của lệnh git gc.

Tổng quan về Git Prune

Để hiểu được các tác động của git prunechúng ta cần mô phỏng một kịch bản trong đó một cam kết trở nên không thể truy cập được. Sau đây là một chuỗi các thực thi dòng lệnh sẽ mô phỏng trải nghiệm này.

~ $ cd git-prune-demo/
~/git-prune-demo $ git init .
Initialized empty Git repository in /Users/kev/Dropbox/git-prune-demo/.git/
~/git-prune-demo $ echo "hello git prune" > hello.txt
~/git-prune-demo $ git add hello.txt
~/git-prune-demo $ git commit -am "added hello.txt"

Chuỗi lệnh trước sẽ tạo ra một kho lưu trữ mới trong một thư mục có tên git-prune-demo. Một cam kết bao gồm một tệp mới hello.textđược thêm vào repo với nội dung cơ bản là "xin chào git prune". Tiếp theo, chúng tôi sẽ tạo sửa đổi hello.txtvà tạo một cam kết mới từ những sửa đổi đó.

~/git-prune-demo $ echo "this is second line txt" >> hello.txt
~/git-prune-demo $ cat hello.txt
hello git prune
this is second line txt
~/git-prune-demo $ git commit -am "added another line to hello.txt"
[master 5178bec] added another line to hello.txt
1 file changed, 1 insertion(+)

Bây giờ chúng tôi có một lịch sử cam kết 2 trong repo demo này. Chúng tôi có thể xác minh bằng cách sử dụng git log:

~/git-prune-demo $ git log
commit 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 14:49:59 2018 -0700

        added another line to hello.txt

commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

        added hello.txt

Đầu git logra hiển thị 2 cam kết và thông báo cam kết tương ứng về các chỉnh sửa được thực hiện hello.txt. Bước tiếp theo là để chúng tôi thực hiện một trong những cam kết không thể truy cập được. Chúng tôi sẽ làm điều này bằng cách sử dụng git resetlệnh. Chúng tôi đặt lại trạng thái của repo về cam kết đầu tiên. cam kết "đã thêm hello.txt".

~/git-prune-demo $ git reset --hard 994b122045cf4bf0b97139231b4dd52ea2643c7e
HEAD is now at 994b122 added hello.txt

Nếu bây giờ chúng ta sử dụng git logđể kiểm tra trạng thái của kho lưu trữ, chúng ta có thể thấy rằng chúng ta chỉ có một cam kết

~/git-prune-demo $ git log
commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

        added hello.txt

Kho lưu trữ demo hiện ở trạng thái chứa một cam kết tách rời. Cam kết thứ hai mà chúng tôi đã thực hiện với thông báo "đã thêm một dòng khác vào hello.txt" không còn được hiển thị trong git logđầu ra và hiện đã được tách ra. Có vẻ như chúng tôi đã mất hoặc xóa cam kết, nhưng Git rất nghiêm ngặt về việc không xóa lịch sử. Chúng tôi có thể xác nhận nó vẫn có sẵn, nhưng tách ra, bằng cách sử dụng git checkoutđể truy cập trực tiếp:

~/git-prune-demo $ git checkout 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Note: checking out '5178becc2ca965e1728554ce1cb8de2f2c2370b1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

      git checkout -b <new-branch-name>

HEAD is now at 5178bec... added another line to hello.txt
~/git-prune-demo $ git log
commit 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 14:49:59 2018 -0700

      added another line to hello.txt

commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

      added hello.txt

Khi chúng tôi kiểm tra cam kết tách ra, Git đủ chu đáo để cung cấp cho chúng tôi một thông điệp chi tiết giải thích rằng chúng tôi đang ở trong trạng thái tách rời. Nếu chúng ta kiểm tra nhật ký ở đây, chúng ta có thể thấy rằng cam kết "đã thêm một dòng khác vào hello.txt" hiện đã quay trở lại trong đầu ra nhật ký! Bây giờ chúng ta biết kho lưu trữ ở trạng thái mô phỏng tốt với một cam kết tách rời mà chúng ta có thể thực hành sử dụng git prune. Trước tiên, chúng ta hãy trở lại masterchi nhánh bằng cách sử dụnggit checkout

~/git-prune-demo $ git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

      5178bec added another line to hello.txt

If you want to keep it by creating a new branch, this may be a good time
to do so with:

     git branch <new-branch-name> 5178bec

Switched to branch 'master'

Khi trở về với chủ nhân thông qua git checkout, Git một lần nữa đủ chu đáo để cho chúng tôi biết rằng chúng tôi đang để lại một cam kết tách rời phía sau. Bây giờ là lúc để cắt tỉa các cam kết tách ra! Tiếp theo, chúng tôi sẽ thực thi git prunenhưng chúng tôi phải chắc chắn chuyển một số tùy chọn cho nó. --dry-runvà --verbosesẽ hiển thị đầu ra cho biết những gì được thiết lập để được cắt tỉa nhưng không thực sự cắt tỉa nó.

~/git-prune-demo $ git prune --dry-run --verbose

Lệnh này rất có thể sẽ trả về đầu ra trống. Đầu ra trống rỗng ngụ ý rằng prune sẽ không thực sự xóa bất cứ điều gì. Tại sao điều này sẽ xảy ra? Vâng, cam kết rất có thể không tách ra hoàn toàn. Ở đâu đó Git vẫn đang duy trì một tài liệu tham khảo về nó. Đây là một ví dụ điển hình về lý do tại sao git prunekhông được sử dụng độc lập bên ngoài git gc. Đây cũng là một ví dụ điển hình về việc khó có thể mất hoàn toàn dữ liệu với Git.

Rất có thể Git đang lưu trữ một tham chiếu đến cam kết tách rời của chúng tôi trong reflog. Chúng tôi có thể điều tra bằng cách chạy git reflog. Bạn sẽ thấy một số kết quả mô tả chuỗi các hành động chúng tôi đã thực hiện để đến đây. Để biết thêm thông tin về việc git reflogtruy cập git reflogtrang. Ngoài việc lưu giữ lịch sử trong reflog, Git có ngày hết hạn nội bộ khi nó sẽ cắt tỉa các cam kết tách ra. Một lần nữa, đây là tất cả các chi tiết thực hiện git gcxử lý và git prunekhông nên được sử dụng độc lập.

Để kết thúc git prunebản demo mô phỏng của chúng tôi, chúng tôi phải xóa reflog

~/git-prune-demo $ git reflog expire --expire=now --expire-unreachable=now --all

Lệnh trên sẽ buộc hết hạn tất cả các mục vào reflog cũ hơn bây giờ. Đây là một lệnh tàn bạo và nguy hiểm mà bạn không bao giờ phải sử dụng như người dùng Git thông thường. Chúng tôi đang thực hiện lệnh này để chứng minh một thành công git prune. Với việc reflog hoàn toàn bị xóa sạch, bây giờ chúng ta có thể thực thi git prune.

~/git-prune-demo $ git prune --dry-run --verbose --expire=now
1782293bdfac16b5408420c5cb0c9a22ddbdd985 blob
5178becc2ca965e1728554ce1cb8de2f2c2370b1 commit
a1b3b83440d2aa956ad6482535cbd121510a3280 commit
f91c3433eae245767b9cd5bdb46cd127ed38df26 tree

Lệnh này sẽ xuất ra một danh sách các tham chiếu đối tượng Git SHA trông giống như ở trên.

Sử dụng

git prune có một danh sách ngắn các tùy chọn mà chúng tôi đề cập trong phần tổng quan.

-n --dry-run

Đừng thực hiện cắt tỉa. Chỉ cần hiển thị một đầu ra của những gì nó sẽ làm

-v --verbose

Hiển thị đầu ra của tất cả các đối tượng và hành động được thực hiện bởi prune

--progress

Hiển thị đầu ra cho biết tiến trình của mận

--expire <time>

Buộc hết hạn các đối tượng đã qua <time>

<head>…

Chỉ định một <head>sẽ duy trì bất kỳ tùy chọn từ ref đó

Thảo luận

Sự khác biệt giữa Git Prune, Git Fetch --prune và Git Remote Prune là gì?

git remote prunevà git fetch --prunelàm điều tương tự: xóa các ref cho các nhánh không tồn tại trên remote. Điều này rất mong muốn khi làm việc trong một quy trình làm việc nhóm trong đó các nhánh từ xa bị xóa sau khi hợp nhất master. Lệnh thứ hai, git fetch --prunesẽ kết nối với điều khiển từ xa và tìm nạp trạng thái từ xa mới nhất trước khi cắt tỉa. Nó thực chất là sự kết hợp của các lệnh:

git fetch --all && git remote prune

Lệnh chung git prunelà hoàn toàn khác nhau. Như đã thảo luận trong phần tổng quan, git prune sẽ xóa các xác nhận tách rời cục bộ.

Làm thế nào để tôi làm sạch các chi nhánh lỗi thời?

git fetch --prunelà tiện ích tốt nhất để làm sạch các chi nhánh lỗi thời. Nó sẽ kết nối với một kho lưu trữ từ xa được chia sẻ từ xa và tìm nạp tất cả các ref chi nhánh từ xa. Sau đó nó sẽ xóa các ref từ xa không còn được sử dụng trên kho lưu trữ từ xa.

Git Remote Prune Origin có xóa Chi nhánh địa phương không?

Không git remote prune originsẽ chỉ xóa các ref cho các nhánh từ xa không còn tồn tại. Git lưu trữ cả refs địa phương và từ xa. Một kho lưu trữ sẽ có local/originvà remote/originbộ sưu tập ref. git remote prune originsẽ chỉ cắt tỉa các ref trong remote/origin. Điều này an toàn để lại công việc địa phương trong local/origin.

Tóm tắt Git Prune

Các git prunelệnh được thiết kế để được viện dẫn như một lệnh đứa trẻ git gc. Rất khó có khả năng bạn sẽ cần phải gọi git prunenăng lực kỹ thuật phần mềm hàng ngày. Các lệnh khác là cần thiết để hiểu tác dụng của git prune. Một số lệnh sử dụng trong bài viết này là git loggit reflog, và git checkout.

» Next: Git: Git Bash
« Prev: Git: Git gc
Các khóa học qua video dành cho Hội viên:
Python Lập trình C Java C# SQL Server PHP HTML5-CSS3-JavaScript
<76K/month for all. Đăng ký Hội viên
Copied !!!