Thiết lập lại cứng của một tập tin


1006

Tôi hiện có ba tệp sửa đổi trong thư mục làm việc của tôi. Tuy nhiên tôi muốn một trong số chúng được đặt lại về trạng thái CHÍNH.

Trong SVN, tôi sẽ sử dụng svn revert <filename>(theo sau svn update <filename>nếu cần) nhưng trong Git tôi nên sử dụng git reset --hard. Tuy nhiên lệnh này không thể hoạt động trên một tập tin duy nhất.

Có cách nào trong Git để loại bỏ các thay đổi thành một tệp duy nhất và ghi đè lên nó bằng một bản sao CHÍNH không?


3
git checkoutdưới đây là câu trả lời. Trong git, "hoàn nguyên" là một cái gì đó bạn làm với một cam kết. "Hoàn nguyên" phát lại nghịch đảo của một cam kết lịch sử vào thư mục làm việc của bạn, do đó bạn có thể thực hiện một cam kết mới "hoàn tác" cam kết được hoàn nguyên. Tôi thấy đây là một điểm thường xuyên gây nhầm lẫn cho những người đến với git từ svn.
Dan Ray


Nếu bạn quan tâm tại sao bạn không thể thực hiện thiết lập lại cứng với các đường dẫn, hãy xem câu trả lời của tôi ở đó .
người dùng

Câu hỏi này giả định rằng người ta biết Hard reset là gì.

Câu trả lời:


1810

Bạn có thể sử dụng lệnh sau:

git checkout HEAD -- my-file.txt

... sẽ cập nhật cả bản sao làm việc my-file.txtvà trạng thái của nó trong chỉ mục với trạng thái từ CHÍNH.

--về cơ bản có nghĩa là: coi mọi đối số sau điểm này là tên tệp . Thêm chi tiết trong câu trả lời này . Cảm ơn VonC đã chỉ ra điều này.


58
Câu trả lời đầy đủ hơn. 1;) Đối với '-', thấy cũng stackoverflow.com/questions/6561142/... (và, nói chung, stackoverflow.com/questions/1192180/... )
VonC

8
Ngoài ra, đừng quên bạn có thể tham khảo một cam kết trước đó HEAD~1để chỉ ra cam kết áp chót.
Ryanmt

14
Bạn có thể rời khỏi HEADnếu bạn đang đứng đầu chi nhánh hiện tại - xem norbauer.com/rails-consulting/notes/ mẹo
cxw

4
Bất kỳ thông tin chi tiết nào tại sao resetlệnh (như đã nói) "không thể thiết lập lại cứng với đường dẫn", và tại sao checkoutlệnh không (không thể?) Được sử dụng để thiết lập lại toàn bộ tập hợp? (Ý tôi là tại sao nó lại được thiết kế như vậy.)
Sz.

1
@cxw Thật không may, điều này không hoàn toàn đúng. Từ trang man của git checkout: "Ghi đè đường dẫn trong cây làm việc bằng cách thay thế bằng nội dung trong chỉ mục hoặc trong <cây-ish>". Tức <tree-ish>là nếu bị bỏ qua, bất kỳ nội dung nào trong chỉ mục sẽ được sử dụng để cập nhật cây làm việc. Điều này có thể hoặc không khác với ĐẦU.
tuntap

137

Đặt lại về đầu:

Để cứng thiết lập lại một tập tin duy nhất thành CHÍNH:

git checkout @ -- myfile.ext

Lưu ý đó @là viết tắt của HEAD. Một phiên bản cũ hơn của git có thể không hỗ trợ mẫu ngắn.

Đặt lại về chỉ mục:

Để cứng thiết lập lại một tập tin duy nhất vào chỉ mục , giả sử chỉ mục không trống, nếu không thì TRÊN:

git checkout -- myfile.ext

Vấn đề là để an toàn, bạn không muốn rời khỏi @hoặc ra HEADkhỏi lệnh trừ khi bạn đặc biệt chỉ thiết lập lại chỉ mục .


1
Có chuyện gì với "-" trước myfile.ext?
Lance Kind

3
@LanceKind Theo tôi hiểu, điều đó được sử dụng để phân định danh sách các tên tệp theo sau nó. Không có nó, có những trường hợp khi git diễn giải các đối số không chính xác.
Acumenus

2
Không chỉ tên tập tin. Quy ước được sử dụng rộng rãi tách biệt các tùy chọn khỏi các đối số vị trí trong nhiều tiện ích. Xem man bashtrang. Cũng được đề cập trong câu trả lời này: unix.stackexchange.com/a/187548/142855
Boweeb

1
Thông thường, --được sử dụng để nói với chương trình I've finished specifying "options", and from here on, everything will be a positional argument.. Thông thường, "tùy chọn" là các mã thông báo giống như --recursivecó thể xuất hiện theo bất kỳ thứ tự nào, hoặc thậm chí được kết hợp với nhau ở dạng ngắn, như với rm -rf. Ngược lại, "đối số vị trí" rất giống với các đối số được truyền cho một hàm trong ngôn ngữ lập trình: vị trí của chúng trong danh sách mã thông báo xác định chính xác chương trình sẽ làm gì với chúng (đây thường là tên tệp). --loại bỏ sự mơ hồ như là cái nào
iono

42

Để trở lại thượng nguồn / chủ làm:

git checkout upstream/master -- myfile.txt

19

Kể từ Git 2.23 (tháng 8 năm 2019), bạn có thể sử dụng restore( thông tin thêm ):

git restore pathTo/MyFile

Trên đây sẽ khôi phục MyFiletrên HEAD(cam kết cuối cùng) trên chi nhánh hiện hành.

Nếu bạn muốn nhận được các thay đổi từ các cam kết khác, bạn có thể quay lại lịch sử cam kết. Lệnh dưới đây sẽ nhận được MyFilehai lần xác nhận trước đó đến lần cuối cùng. Bây giờ bạn cần tùy chọn -s( --source) kể từ bây giờ bạn sử dụng master~2chứ không phải master(mặc định) khi bạn khôi phục nguồn:

git restore -s master~2 pathTo/MyFile

Bạn cũng có thể lấy các tập tin từ chi nhánh khác!

git restore -s my-feature-branch pathTo/MyFile

1
Cách dễ nhất cho đến nay. Thật không may, câu trả lời này không được chú ý đầy đủ.
số


4

bạn có thể sử dụng lệnh dưới đây để thiết lập lại tập tin duy nhất

git checkout HEAD -- path_to_file/file_name

Liệt kê tất cả các tập tin thay đổi để có được path_to_file/filenamevới lệnh dưới đây

git status

1

Bạn có thể sử dụng lệnh sau:

git reset -- my-file.txt

sẽ cập nhật cả bản sao làm việc my-file.txtkhi được thêm vào.


Không thay đổi nội dung của tệp sửa đổi, theo yêu cầu.
Rafael

Khi bạn thêm vào stash Bạn đã chỉnh sửa tệp?
ĐỊA CHỈ

1
Đó không phải là điểm đặc biệt @ADDQU. Câu hỏi là làm thế nào để "thiết lập lại cứng" một tập tin, không xóa nó khỏi danh sách theo giai đoạn.
Rafael

@Rafael Bạn đúng, nhưng tôi muốn cho bạn biết rằng có một cách quá.
THÊM NGÀY 30/8/19

0

Bạn có thể sử dụng lệnh sau:

git checkout filename

Nếu bạn có một nhánh có cùng tên tệp, bạn phải sử dụng lệnh này:

git checkout -- filename

1
Điều này sẽ không "thiết lập lại cứng" tệp - nó chỉ sao chép trạng thái chỉ mục vào cây làm việc. Một "thiết lập lại cứng" đầu tiên sẽ thiết lập lại chỉ mục.
AH

-21

Một cách đơn giản, dễ dàng, thực hành, giúp bạn thoát khỏi nước nóng, đặc biệt nếu bạn không quá thoải mái với git:

  1. Xem nhật ký của tập tin của bạn

    đăng nhập git myFile.js

    cam kết 1023057173029091u23f01w276931f7f42595f84f Tác giả: kmiklas Ngày: Thứ ba ngày 7 tháng 8 09:29:34 2018 -0400

    JIRA-12345 - Tái cấu trúc với kiến ​​trúc mới.

  2. Lưu ý băm của tập tin:

    1023057173029091u23f01w276931f7f42595f84f

  3. Hiển thị tệp bằng cách sử dụng hàm băm. Hãy chắc chắn rằng đó là những gì bạn muốn:

    chương trình git 1023057173029091u23f01w276931f7f42595f84f: ./ myFile.js

  4. Chuyển hướng tệp đến một bản sao cục bộ

    git show 1023057173029091u23f01w276931f7f42595f84f: ./ myFile.js> myFile.07aug2018.js

  5. Sao lưu tập tin hiện tại của bạn.

    cp myFile.js myFile.bak.js

  6. Mở cả hai tập tin trong trình soạn thảo văn bản yêu thích của bạn.

    vim myFile.js
    vim myFile.07aug2018.js

  7. Sao chép mã n 'dán từ myFile.07aug2018.js vào myFile.js và lưu lại.

  8. Cam kết và đẩy myFile.js

  9. Một lần nữa xem nhật ký và xác nhận rằng tệp của bạn được đặt đúng chỗ.

  10. Nói với khách hàng của bạn để kéo bản mới nhất, vui vẻ xem nó hoạt động với phiên bản cũ tại chỗ.

Không phải là giải pháp gợi cảm nhất, hay git-centric nhất, và chắc chắn là thiết lập lại / đảo ngược "thủ công", nhưng nó hoạt động. Nó đòi hỏi kiến ​​thức tối thiểu về git và không làm xáo trộn lịch sử cam kết.


2
Câu trả lời này phức tạp và dễ bị lỗi hơn nhiều so với bất kỳ giải pháp nào có trước nhiều năm.
Artif3x

2
Tại sao mọi người nên sử dụng giải pháp này!? Câu trả lời đúng chỉ là một lệnh đơn giản.
Milad Rahimi

1
Đây là giải pháp tối ưu cho một số trường hợp nhất định. Nó có giá trị cho những người trong một ràng buộc, trong đó git bị trục trặc, và cho những người cần một công việc xung quanh.
kmiklas
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.