Xuất stash sang máy tính khác


296

Tôi cần một cách để xuất một thay đổi được lưu trữ sang một máy tính khác.

Trên Computer1 tôi đã làm

$ git stash save feature

Tôi đang cố gắng lấy bản vá stash vào một tệp và sau đó nhập nó vào một máy tính khác

$ git stash show -p > patch

Lệnh này cung cấp cho tôi một tệp mà tôi có thể di chuyển đến một máy tính khác, nơi repo này được sao chép, nhưng câu hỏi là làm thế nào để nhập lại nó dưới dạng stash.

Cảm ơn


6
fyi git stash savehiện không được ủng hộgit stash push
Ewan

Câu trả lời:


290

Bạn có thể áp dụng tệp vá (chưa thực hiện các thay đổi) bằng cách chạy đơn giản

git apply patchfile

Sau đó, bạn có thể chỉ cần tạo một stash mới từ thư mục làm việc hiện tại:

git stash

2
@Marcelo A: Rất tốt để nghe, nhưng vui lòng đánh dấu các câu trả lời bạn đã chấp nhận bằng cách nhấp vào dấu kiểm lớn bên dưới số phiếu bầu của câu trả lời. Bằng cách đó, câu hỏi của bạn sẽ được đánh dấu là giải quyết.
chọc

2
Lưu ý rằng hệ thống sẽ không để OP đánh dấu câu trả lời là "được chấp nhận" cho đến khi nào đó (15 phút, tôi nghĩ) đã trôi qua kể từ khi câu hỏi được hỏi.
Greg Hewgill

23
Sau khi đọc câu trả lời này, một điều tôi đã tự hỏi là làm thế nào để chọn một stash cụ thể từ tất cả các stash của tôi. Câu trả lời cho điều đó là ở đây: stackoverflow.com/a/1910142/1148702 . Trong trường hợp này, tôi đã kết thúc: git stash show "stash@{0}" -p > patchthay vì lệnh shell thứ hai của OP.
Tim Camber

1
@TimCamber Tôi không nghĩ bạn cần báo giá kép xung quanh stash@{0}..
ari gold

2
@arigold Phụ thuộc vào vỏ bạn đang sử dụng. Ví dụ: trong PowerShell, bạn cần chúng vì dấu ngoặc nhọn là một cú pháp đặc biệt ở đó.
chọc

18

cách khác, bạn có thể tạo một nhánh từ stash của mình (trên máy tính 1), bằng cách sử dụng

git stash branch stashed_changes_branch

cam kết thay đổi của bạn:

git commit -a

sau đó thêm nó dưới dạng điều khiển từ xa trên máy tính 2:

git remote add pc1 user@computer1:/path/to/repo

bây giờ bạn có thể lấy thông tin từ xa bằng cách sử dụng

git fetch pc1

bây giờ bạn có thể nhập cam kết theo cách bạn muốn; sử dụng git cherry-pick , git rebase hoặc bất cứ thứ gì bạn thích ... Nếu bạn muốn nó trông giống như bạn vừa áp dụng git stash ; bạn có thể sử dụng git cherry-pick --no-commit.


Nếu bạn không có kết nối trực tiếp giữa computer1 và computer2; bạn có thể sử dụng một điều khiển từ xa (như github hoặc một cái gì đó tương tự):

git push origin stashed_changes_branch

và trên máy tính2:

git fetch

1
Điều này giả định rằng hệ thống nguồn (computer1) mở để nhận các kết nối bên ngoài mà hầu hết mọi người hạ cánh ở đây không có khả năng là đúng. Nếu bạn muốn đi theo con đường chi nhánh, tại sao không chỉ đẩy một nhánh tạm thời đến nguồn gốc từ xa và kéo nó từ máy tính2? Bạn có thể xóa chi nhánh từ xa ngay khi bạn đã kéo nếu bạn không muốn giữ nó xung quanh. Chi nhánh trong git rất rẻ thường có vài lý do để không sử dụng chúng.
không thể chia sẻ

@indivisible Tôi không đồng ý có rất nhiều cơ hội để kết nối hai máy tính trên internet ngày hôm nay. Kỹ thuật được mô tả trong câu trả lời có thể hữu ích khi chuyển một công việc đang tiến hành từ máy tính xách tay sang máy tính để bàn trên mạng LAN. Ngay cả một dịch vụ vpn ảo như Hamachi cũng sẽ được sử dụng để truyền tệp qua internet ở bất cứ đâu trực tiếp giữa các máy tính chạy git.
steampowered

1
@steampowered, chắc chắn nó thể đúng với một số người / tình huống nhưng tôi nghĩ rằng đó là một điểm đáng chú ý đối với các độc giả tương lai vì đây là một yêu cầu khó đối với giải pháp này để làm việc và sửa đổi hệ thống / env cục bộ của bạn để chấp nhận lưu lượng truy cập đến không cần cấu hình tầm thường rằng, theo tôi, là "quá mức" cho một nhiệm vụ như thế này. Nếu (các) hệ thống của bạn đã mở thì bằng mọi cách hãy sử dụng câu trả lời này - nó không sai. Tôi chỉ cảm thấy rằng phần lớn người dùng hạ cánh ở đây sẽ không ở trong tình huống như vậy.
không thể phân chia

Stash là các đối tượng cam kết và do đó đã có một hàm băm xác nhận (xem git stash list --oneline), vì vậy về mặt kỹ thuật, bạn không phải áp dụng stash cho một đối tượng cam kết mới. Nói cách khác, tạo một chi nhánh mới là không cần thiết. Tuy nhiên, việc đẩy một stash trực tiếp vào một điều khiển từ xa là rất khó để nói.
Tyler Crompton

15

Ngoài ra, bạn có thể xuất toàn bộ stash cục bộ sang một compter khác như sau

  • git pull trên cả thư mục git cũ và mới của bạn để đảm bảo rằng cả hai đều có những thay đổi mới nhất.
  • sao chép thư mục .git từ thư mục git cũ sang kho lưu trữ mới

1
Mặc dù tar nén của .git là 700M +, nhưng điều này hóa ra dễ dàng hơn nhiều so với các giải pháp được đề xuất khác, đặc biệt là khi tôi có nhiều stash.
Chris Warth

5

Cách thực hiện xuất Stash trong SourceTree:

  1. Tạo một nhánh mới "StashTransfer" từ một nhánh nơi bạn sẽ sử dụng Stash của mình
  2. Áp dụng stash của bạn cho nó và thực hiện một cam kết

  3. Nhấp vào cam kết của bạn và tạo một bản vá từ nó, mang theo tệp vá với bạn.

  4. Chuyển đến một kho lưu trữ khác, chọn cùng một nhánh cha mà bạn vừa sử dụng trong 1)

  5. Hành động / Áp dụng Bản vá, chọn Chế độ: Sửa đổi tệp sao chép đang hoạt động, đẩy Áp dụng Bản vá ngay bây giờ bạn có các sửa đổi không được cam kết từ bản vá trong môi trường làm việc hiện tại của bạn

  6. Tạo một Stash mới cho repo hiện tại


4

Bạn có thể tạo tệp stash dưới dạng tệp vá từ một máy, sau đó có thể chia sẻ tệp vá đó với các máy khác.

Tạo stash như một bản vá

$ git stash show "stash@{0}" -p > changes.patch

Stash của người dùng @ {0}. Đây là bản giới thiệu của stash. Nó sẽ tạo tập tin vá với bản stash mới nhất. Nếu bạn muốn sử dụng một lệnh khác nhau $ git stash listđể xem danh sách stash của bạn và chọn cái nào bạn muốn vá.

Áp dụng các bản vá

Bây giờ chuyển stash đó sang một máy khác và dán nó vào thư mục gốc của dự án của bạn. Sau đó chạy lệnh này

$ git apply changes.patch

Nếu có lỗi và bạn muốn đảo ngược sự thay đổi

$ git apply changes.patch --reverse

3

Một lựa chọn khác là để rsynccác .gitthư mục từ máy này sang máy tính khác. rsyncxử lý chỉ thay đổi tập tin (nhanh hơn một bản sao).

Một nhược điểm của phương pháp này là các cấu hình cũng sẽ bị ghi đè, điều này có thể không mong muốn nếu bạn chạy các cấu hình .git khác nhau giữa hai máy. Nhưng bạn có thể khắc phục điều này bằng cách loại trừ các tệp có --excludetùy chọn trong rsync.

Nhìn chung, tôi nghĩ rằng một giải pháp Git bản địa sạch hơn, nhưng bản rsynchack này có thể tốt cho những người vội vàng, người có thể quen thuộc với rsync hơn git.


3

Lệnh khởi động từ bài viết gốc:

git stash show -p stash@{x} > patch_file

không làm việc cho tôi (vì một số lý do nó tạo ra các tệp vá không sử dụng được). Thay vào đó tôi đã phải:

git stash apply stash@{x}
git commit

cho mỗi stash tôi muốn chuyển. Sau đó, tôi đã đặt repo 'cha mẹ' trong tệp: /// phạm vi của repo 'con' và thực hiện như sau, cho mỗi lần xác nhận stash:

git fetch file:///path_to_parent_git && git cherry-pick commit_sha
git reset --soft HEAD^
git stash save my_new_stash_on_child

Điều này phức tạp hơn nhưng đã lừa tôi.


0

Nếu bạn muốn chuyển các thay đổi của mình từ máy này sang máy khác, bạn luôn có thể cam kết các thay đổi của mình trên máy và sau đó thực hiện đặt lại mềm trên máy của họ.

Văn phòng

git commit -m "-stash-"

Phòng bếp

git reset --soft HEAD~1


0

Stash là một cam kết hợp nhất đặc biệt của cây công việc giữa cam kết cơ sở và chỉ mục. Một cách có thể là lưu từng bản vá riêng biệt, kiểm tra stash cha mẹ đầu tiên, khôi phục chỉ mục và cây công việc từ hai bản vá và cuối cùng khôi phục lại bản gốc (có vẻ như một câu trả lời theo cách này).

Điều này là cần thiết để tạo lại đầy đủ tất cả thông tin từ stash và nếu bạn không quan tâm đến điều đó thì ít nhất bạn nên kiểm tra cha mẹ đầu tiên của stash trước khi khôi phục để tránh xung đột và theo dõi nơi stash được tạo.

Đây là những gì tôi đã làm để khôi phục hoàn toàn tất cả các stash từ repo này sang repo khác. Nếu bạn không thể có chúng trên cùng một máy tính, bạn có thể lưu các thẻ stash trong một gói sau khi tạo chúng và sao chép danh sách refs và gói vào máy tính đích.

Từ gốc của repo gốc:

  1. Lấy danh sách các stash ref
  2. Gắn thẻ giới thiệu stash của bạn để bạn có thể truy xuất chúng bằng git fetch (tên thẻ không phải là vấn đề, thay đổi nó nếu có xung đột. Tôi đã sử dụng stash_+ số trong tham chiếu stash logic)
  3. Chuyển đổi các tham chiếu logic thành băm sha1 theo thứ tự ngược lại - chúng tôi sẽ sử dụng chúng sau
  4. Lưu đường dẫn repo đó - cũng để sau
refs=$(git stash list|cut -d: -f1)
for ref in $refs; do tag stash_${ref//[^0-9]} $ref; done
refs=$(git rev-parse $refs|tac)
oldpath=$PWD

NB: Điều này yêu cầu bash hoặc shell tương thích (ksh, zsh nên làm ...) Bạn cũng có thể tăng một biến, ví dụ stash_$((i++))nếu shell của bạn không hỗ trợ${param//pattern}

Bây giờ trong repo mới, cho mỗi ref:

  1. Tìm nạp ref từ repo cũ (chúng tôi thậm chí không cần sử dụng tên thẻ, vì chúng tôi đã gắn thẻ chúng, chúng tôi có thể truy xuất chúng bằng git fetch)
  2. Nhập lại stash từ ref, sử dụng chủ đề của ref đó làm thông điệp stash.
for ref in $refs; do git fetch $oldpath $ref; git stash store -m "$(git show -s --pretty=%s $ref)" $ref; done
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.