2011-08-22 28 views
18

Thường xuyên khi làm việc trên chi nhánh tôi cần giới thiệu một số thay đổi "tạm thời" (chẳng hạn như thông tin gỡ lỗi bổ sung hoặc thay đổi cho phép tôi quan sát tốt hơn điều tôi đang thực sự là đang hoạt động).Xử lý các thay đổi tạm thời (không cam kết) trong Git

Về những thay đổi này "tạm thời":

  • Tôi muốn họ trong bản sao làm việc của tôi của chi nhánh của tôi, vì họ giúp tôi làm việc về việc thay đổi thực tế,
  • Tôi không muốn họ cam kết với chi nhánh, bởi vì chi nhánh sẽ được sáp nhập vào tổng thể một thời gian và họ không phải là mã sản xuất.

Hiện tại tôi chỉ giữ chúng dưới dạng không bị giới hạn và tôi bỏ qua chúng theo cách thủ công khi dàn dựng mọi cam kết. Tuy nhiên tôi không thể ở lại với giải pháp này vì:

  • Tất cả thời gian tôi phải nhớ những tập tin mà tôi cần phải bỏ qua,
  • Một ngày nào đó tôi sẽ kết thúc với 2 thay đổi trong một tập tin, một là tạm thời, một được cam kết, và nó sẽ thực sự rắc rối.

Tôi nên xử lý vấn đề này như thế nào?


gitignore rõ ràng là ra câu hỏi bởi vì tôi không muốn bỏ qua toàn bộ các file và tôi vẫn còn quan tâm đến những thay đổi từ committers khác (tôi cần phải rebase chi nhánh để làm chủ bất cứ lúc nào) .

+0

Dường như là một ý tưởng thú vị để thử mở rộng bỏ qua thông tin chi tiết. Thậm chí có thể có giá trị cố gắng để yêu cầu trên danh sách gửi thư git (bạn không cần phải đăng ký để đăng bài và vì nó là khối lượng khá cao, có thể bạn không muốn). –

+0

Trên thực tế gitignore không nằm ngoài câu hỏi, bởi vì nếu tập tin được phiên bản, bạn * sẽ * nhận được phiên bản cam kết của nó. Nó chỉ thêm rằng sẽ bỏ qua nó. Tuy nhiên, nó không xử lý các trường hợp khi bạn muốn bỏ qua chỉ một số thay đổi cho một tập tin cụ thể và sớm hay muộn bạn muốn. –

+0

Tôi đã thêm một ý tưởng của riêng mình, có vẻ ổn với tôi nhưng tôi đánh giá cao nếu một người nào đó có kinh nghiệm hơn có thể có một cái nhìn nếu không có vấn đề với nó. – Kos

Trả lời

12

tôi thường đối phó với điều này bằng cách sử dụng:

git add -p 

... đến giai đoạn thay đổi hunk-by-hunk. Sau đó, bạn chỉ cần đảm bảo nhấn n để thay đổi gỡ lỗi của mình.


Nếu tôi có thay đổi tham gia nhiều hơn của loại hình này, tôi sẽ tạo ra một chi nhánh gọi là cái gì đó như local-changes với một cam kết tại đỉnh của nó giới thiệu mã gỡ lỗi. Sau khi tạo thêm một số cam kết, sau đó tôi sẽ sử dụng:

git rebase -i master 

... để sắp xếp lại chúng để cam kết với các thay đổi cục bộ ở đầu một lần nữa. Sau đó, để cập nhật chính và quay lại nhánh thay đổi cục bộ, bạn có thể làm:

git checkout master 
git merge local-changes^ 
git checkout local-changes 
+0

Chọn các thay đổi có liên quan theo cách thủ công là những gì tôi đang cố tránh ở đây :) Tôi chỉ muốn thực hiện một lần. – Kos

+1

:) Vâng, tôi đã thêm một đề xuất thay thế cho câu trả lời của tôi. –

0

Chức năng stash của GIT cung cấp chính xác những gì bạn đang yêu cầu. Ít nhất là cho phần "giữ". Làm tốt/xấu lựa chọn khi cam kết không thể tránh được như thế này.

6

Hãy thử git update-index --assume-unchanged <file>. Bằng cách này git sẽ không thêm tệp vào chỉ mục khi sử dụng git add hoặc git commit -a.

EDIT: Điều này không cho phép bạn xử lý trường hợp có một tệp với cả thay đổi tạm thời và vĩnh viễn.

+0

Có lẽ đáng để chỉ ra hậu quả của việc sử dụng '--assume-constant' cũng có thể rất khó hiểu :) –

+1

@Mark Tôi chưa bao giờ nhầm lẫn khi sử dụng' --assume-constant'. Bạn có thể xây dựng? Khó khăn duy nhất tôi gặp phải một hoặc hai lần là tìm ra tệp nào được đặt cờ này. –

+0

Thật dễ dàng để quên rằng bạn đã sử dụng nó. Đó có thể chỉ là tôi ... –

2

Bạn có thể sử dụng

git stash 

để lưu nó vào một không gian tạm thời. Sau khi hợp nhất, bạn có thể sử dụng

git stash pop 

để tải lại các thay đổi tạm thời vào thư mục làm việc của bạn.

+0

điều này không phân biệt giữa những thay đổi hữu ích trên toàn cầu và thay đổi cục bộ, như OP được yêu cầu .. – naught101

0

Tôi có xu hướng giữ những thay đổi không được cam kết như vậy. Tôi chỉ đơn giản là luôn luôn sử dụng git add -i hoặc git add -p để thay đổi giai đoạn (trừ khi tôi chắc chắn tôi muốn tất cả các thay đổi cây có). Bằng cách đó tôi xem xét tất cả những thay đổi tôi muốn cam kết và dễ dàng bỏ qua những thay đổi tạm thời. Nó cũng giúp giai đoạn thay đổi bạn biết bạn sẽ muốn cam kết sớm và giữ cho chúng dàn dựng hoặc thậm chí cam kết và hơn là thêm nhiều thay đổi với git commit --amend.

4

Đây là cách để giải quyết vấn đề này, khi đã thiết lập, chỉ yêu cầu bạn nhớ một bước để thiết lập và một bước trước mỗi lần nhấn.

Các thiết lập:

git branch tempChanges [branch for temporary changes] 
    [create your temporary changes] 
git add -A 
git commit 

Lưu ý sha cho rằng cam kết. Sau đó, chuyển sang nhánh đang hoạt động của bạn và:

git cherry-pick shaOfTempChangesCommit 

Bây giờ bạn có thay đổi về chi nhánh đang hoạt động của bạn. Làm công việc của bạn và thực hiện cam kết. Sau đó, trước khi bạn đẩy:

git rebase -i 

Bạn sẽ thấy một cái gì đó như thế này:

pick bfd4d2e This first commit is your temporary changes. 
pick 186a99d Some stuff done on the working branch. 
pick ec871c6 More stuff done on the working branch. 
(etc.) 

Xóa phù hợp với những thay đổi tạm thời của bạn. Sau đó lưu và thoát. Lịch sử của bạn sẽ được viết lại để loại trừ các thay đổi tạm thời. (Các thay đổi sẽ vẫn tồn tại trong chi nhánh tempChanges.) Khi đã xong, hãy thực hiện bất kỳ thử nghiệm nào bạn cần và sau đó git push.

Khi bạn đã sẵn sàng để làm việc một lần nữa, bạn có thể kéo những thay đổi tạm thời trở lại chi nhánh làm việc hiện tại của bạn (hoặc một chi nhánh làm việc mới):

git cherry-pick shaOfTempChangesCommit 

Vì vậy, trong tổng, tất cả các bạn có cần nhớ trong phương pháp này là

  • sau khi bạn tạo một chi nhánh làm việc

    git cherry-pick shaOfTempChangesCommit

  • sau khi bạn đã hoàn tất công tác và sẵn sàng để đẩy

    git rebase -i[để loại bỏ những thay đổi tạm thời trước khi bạn đẩy]

1

Tôi đã tìm thấy một giải pháp sạch cho vấn đề này : (tha thứ cho nghệ thuật ascii của tôi). Nó đòi hỏi một nhánh bổ sung cho nhánh chủ đề. (điều này có sai sót và đang được tranh chấp/sửa chữa, xem ý kiến)

Công việc trông như thế này ban đầu:

master 
    \ 
     \ 
    commit1 ---- commit2 ---- "branch" 

làm việc được thực hiện trên "chi nhánh".

Để giới thiệu một số thay đổi tạm thời:

  • tạo nhánh "ngành tạm" từ "bậc thầy"
  • cam kết những thay đổi tạm thời có
  • rebase "chi nhánh" từ "bậc thầy" lên " chi nhánh-temp "

Repo giờ có dạng:

master 
    \ 
     \ 
    "branch-temp" ----- commit1 ---- commit2 ---- "branch" 

Công việc hiện đang được tiếp tục vui vẻ trên chi nhánh và những thay đổi tạm thời không hiển thị trong trạng thái.

Để thay đổi hoặc mở rộng những thay đổi tạm thời:

  • kiểm tra chi nhánh-temp
  • cam --amend những thay đổi tạm thời có - điều này là sai, vì nó làm cho "ngành tạm thời" bất đồng

để trộn các thay đổi từ chi nhánh để làm chủ:

Điều này chỉ phức tạp hơn một chút. Chúng tôi muốn hợp nhất trong tất cả các thay đổi, ngoại trừ những thay đổi được giới thiệu bởi "branch-temp".Ý tưởng của tôi là:

  • chạy một merge bình thường từ "chi nhánh" lên "bậc thầy"
    (bây giờ chúng tôi có một hợp nhất, nhưng với một số thay đổi tạm thời không cần thiết - chúng ta hãy loại bỏ chúng)
  • git Revert - -không-cam kết chi nhánh-temp
  • git commit --amend
    (hai bước này nên sửa đổi việc hợp nhất cam kết, để nó không còn chứa các thay đổi từ chi nhánh-temp)
+0

Thay vào đó, tôi sẽ rebase lên master, sử dụng rebase tương tác và chỉ loại bỏ các cam kết không được sử dụng (được đánh dấu bằng [test] hoặc một cái gì đó trong chủ đề của chúng). Điều đó cũng sẽ tránh được sự cần thiết của "branch-temp" và dẫn đến lịch sử tuyến tính. –

+0

'git checkout branch-temp' +' git commit --amend' sẽ không hoạt động như được trình bày, vì sau đó 'branch-temp' sẽ có phiên bản mới, nhưng' branch' vẫn sẽ có phiên bản cũ của commit . Và tôi không chắc chắn đồng bằng 'git rebase --onto branch-temp' sẽ sửa lỗi đó. Nó dễ dàng hơn để 'git rebase -i' và chỉnh sửa commit theo cách đó, nhưng điều đó sẽ để lại' branch-temp' phía sau (đó là những gì tôi muốn sử dụng và xóa commit bằng cách rebase hoặc merge + revert). –

+0

Có, bạn đã đúng - tôi đã kiểm tra tài liệu và cam kết --amend tạo một cam kết mới và cập nhật nhánh hiện tại, trong khi tôi nghĩ rằng nó sửa đổi cam kết trên HEAD tại chỗ. – Kos

1

Tôi thường đặt tất cả mã gỡ lỗi của mình vào cam kết của riêng mình, sau đó trước khi tôi hợp nhất, tôi revert cam kết. Tôi đã sử dụng một số biến thể của hầu hết các câu trả lời khác ở lần, nhưng tôi thích điều này vì sự đơn giản của nó và thực tế là nó bảo tồn lịch sử phát triển của tôi. Có, tôi không muốn mã gỡ lỗi của tôi trong sản phẩm cuối cùng, do đó revert, nhưng nếu thử nghiệm tìm thấy một vấn đề tôi muốn có thể phục hồi mã gỡ lỗi đó để tiếp tục làm việc.

+1

Điều đó khiến cây của bạn đầy những cam kết không mong muốn xấu xí ... – naught101

1

Điều gì về cách viết một tập lệnh shell đơn giản sẽ vá và hoàn tác các thay đổi gỡ lỗi của bạn theo yêu cầu (và sau đó biến nó thành bí danh git).

Ví dụ:

git apply-my-debug 
... 
do coding 
... 
git remove-my-debug 
git add . 
git commit -m "Don't worry about debug changes" 
1

Để tránh làm lộn xộn lên khu vực dàn dựng của bạn khi bạn đang tạo một tính năng, cam thay đổi debug của bạn với một sáng nhấp nháy cảnh báo rằng họ không nên làm cho nó thành việc hợp nhất cuối cùng:

#warning - DEBUG ONLY - DO NOT MERGE 

print(debugInfo) 

#warning - DEBUG ONLY - DO NOT MERGE 

Khi bạn đã sẵn sàng hợp nhất chi nhánh, nếu bạn đã quên chúng, những thay đổi này sẽ bị bạn hoặc người khác bắt gặp trong đánh giá mã yêu cầu kéo của bạn.

Sau đó bạn sẽ có nhiều cách khác nhau để loại bỏ các debug cam kết:

  1. revert gỡ lỗi cụ thể cam kết. Điều này sẽ giữ lại lịch sử của họ trong chi nhánh.

  2. cherry-pick số tốt cam kết. Thao tác này sẽ xóa hoàn toàn các cam kết gỡ lỗi.

  3. Một cái gì đó phức tạp hơn như rebase -interactive để xóa các cam kết tại chỗ.

Các vấn đề liên quan