Sử dụng Git trên nhiều hệ thống mà không cần truy cập mạng


84

Tôi muốn sử dụng kiểm soát phiên bản, nhưng vì lý do bảo mật, máy chủ tôi đang làm việc không có quyền truy cập internet: Tôi chỉ có thể di chuyển các tệp trên ổ flash USB. Tôi vẫn có thể sử dụng Git với thiết lập này chứ? Tôi có thể tạo các bản vá nhỏ mà tôi có thể áp dụng trên kho Git không?


65
Tiêu đề của bạn nói không có quyền truy cập mạng, câu hỏi của bạn nói không có quyền truy cập internet; một sự khác biệt rất lớn
tkausl

7
@TutuKaeen Bạn có thể có một mạng cục bộ không được kết nối với internet. Vì vậy, thay vì github.com, bạn thiết lập máy chủ git tại vd. 192.168.1.100 và mọi thứ khác đều hoạt động như nhau.
Đặc vụ_L

12
@TutuKaeen: Câu hỏi quan trọng là liệu giao tiếp mạng trực tiếp (hoặc gián tiếp) có thể thực hiện được giữa hai máy không. Vậy trong trường hợp của bạn, cả hai máy đều được nối mạng, nhưng các mạng được tách ra? Trong trường hợp đó, vui lòng chỉnh sửa thông tin đó vào câu hỏi của bạn.
sleske

15
@TutuKaeen Câu hỏi của bạn vẫn chưa rõ ràng. Bạn nói rằng bạn muốn sử dụng kiểm soát phiên bản, nhưng trong các bình luận của bạn, bạn yêu cầu nó giúp bạn triển khai để sản xuất. Những vấn đề này không phải lúc nào cũng chồng chéo. Tôi nghĩ bây giờ bạn đã có câu trả lời tốt, nhưng trong tương lai sẽ hữu ích nếu câu hỏi của bạn toàn diện hơn về yêu cầu của bạn, có vẻ như: "Tôi muốn sử dụng kiểm soát phiên bản, máy phát triển của tôi không có quyền truy cập internet, nó có quyền truy cập mạng nhưng không vào máy sản xuất và tôi muốn biết làm thế nào để lấy mã ra khỏi kiểm soát phiên bản trên máy sản xuất. "
DavidS

4
Nó chỉ có vẻ kỳ lạ khi sử dụng thuật ngữ servercho một máy không được kết nối với bất kỳ mạng. Nó chỉ có thể là một mạng cục bộ ngay cả khi không có truy cập internet nhưng dù sao nó vẫn là một mạng.
Patrick Gregorio

Câu trả lời:


157

Chắc chắn, không có gì về Git yêu cầu một giao thức cụ thể. Chỉ cần ra khỏi máy khách, máy khách chuẩn hỗ trợ HTTP (S), SSH, giao thức Git tùy chỉnh và quan trọng là giao thức cục bộ . Điều đó chỉ cần một đường dẫn đến một .gitthư mục cục bộ , có thể nằm trong thư mục làm việc ( /path/to/project/.git) hoặc chỉ là một thư mục trống ( /path/to/project.git), mặc dù việc đặt tên chỉ là một quy ước.

Tất nhiên, điều này có nghĩa là bạn có thể thêm ổ đĩa flash dưới dạng điều khiển từ xa:

git remote add origin /mnt/flashdrive/foo.git

hoặc, trên Windows:

git remote add origin F:\foo.git

Hoặc thậm chí thêm nó dưới dạng một điều khiển từ xa bổ sung có tên khác (nếu bạn muốn origintrỏ đến máy chủ Internet ở đâu đó):

git remote add flashdrive /mnt/flashdrive/foo.git

Sau đó, bạn có thể chỉ cần đẩy / kéo đến / từ điều khiển từ xa này giống như bất kỳ điều khiển nào khác.

Nếu bạn đọc tài liệu , bạn sẽ nhận thấy cũng có một file://giao thức hoạt động hơi khác. Bạn nên sử dụng một đường dẫn cục bộ vì nó sẽ sử dụng một số tối ưu hóa bổ sung - nếu bạn sử dụng file://giao thức thì git sẽ sử dụng một số thành phần mạng tiêu chuẩn (để nói chuyện với đĩa cục bộ), tốc độ chậm hơn.


50
Để thêm vào câu trả lời đặc biệt này - Cũng có thể đáng để điều tra bằng cách sử dụng bộ lưu trữ 'trần' trên ổ đĩa flash. Các kho lưu trữ 'trần' không có cây hoạt động, và vì vậy hãy loại bỏ một loại vấn đề tiềm ẩn khi được sử dụng như một 'điểm chính quyền', có vẻ giống như trường hợp sử dụng của OP.
Iron Gremlin

5
Các file://cũng là một chút linh hoạt hơn. Nó cho phép bạn sử dụng một số tính năng (như bản sao nông) mà bạn không thể sử dụng với đường dẫn cục bộ.
Austin Hemmelgarn

1
@IronGremlin Bạn có thể mở rộng về khái niệm "điểm chia sẻ thẩm quyền" này không? Tôi không phải là chuyên gia về Git và tôi tò mò ý của bạn là gì.
Các cuộc đua nhẹ nhàng trong quỹ đạo

2
@LightnessRacesinOrbit - Đây là một chủ đề khá dày đặc, nhưng, về cơ bản, git được phân phối, vì vậy mọi người đều có lịch sử của riêng mình. A có thể hỏi B về phiên bản lịch sử của họ, nhưng C không biết về nó trừ khi có ai đó nói với họ. Có một kho lưu trữ duy nhất để lưu trữ lịch sử 'có thẩm quyền' có nghĩa là D hoạt động như một cơ sở thanh toán bù trừ cho lịch sử. Vì vậy, A nói với D về những thay đổi và B và C biết nói chuyện với D để luôn cập nhật, thay vì làm những việc bên kênh với nhau. Trong trường hợp, nếu máy chủ của OP là C và ổ đĩa flash là D, thì nó đảm bảo rằng máy chủ không bị loại bỏ khỏi các tương tác A / B.
Iron Gremlin

6
@LightnessRacesinOrbit Điều quan trọng cần lưu ý ở đây là trần không có nghĩa là có thẩm quyền, nó chỉ hữu ích trong bối cảnh đó. Ví dụ, nó cũng hữu ích bởi vì, thiếu một cây làm việc, đó là dấu chân không gian đĩa (hoặc băng thông) nhỏ hơn. Điều này từng là một địa ngục quan trọng hơn nhiều so với bây giờ, nhưng vẫn xuất hiện.
Iron Gremlin

46

Trên một đơn máy tính, không có gì đặc biệt là cần thiết. Chạy git inittrong thư mục mong muốn của bạn và làm việc với Git như bình thường.

Để đồng bộ hóa một kho lưu trữ trên nhiều máy tính, có một số phương pháp.

Phương pháp 1a (hoàn toàn không có mạng): Bạn có thể tạo một 'kho lưu trữ trần' trên thanh USB, sau đó ấn vào nó và kéo từ đó như bất kỳ kho lưu trữ từ xa nào khác. Nói cách khác, hoạt động của kho lưu trữ thông qua các đường dẫn cục bộ không có gì khác biệt so với các hoạt động thông qua URL SSH hoặc HTTPS.

  1. Tạo kho lưu trữ 'từ xa':

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. Trong máy tính 1, đẩy mọi thứ vào nó:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. Trong máy tính 2, tốt, giống như mọi khi.

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    

(Bạn cũng có thể đẩy / tìm nạp / kéo từ URL hoặc đường dẫn trực tiếp.)

Phương pháp 1b (mạng nội bộ): Nếu bạn có sẵn máy chủ nội bộ với SSH và nếu đã cài đặt Git, bạn có thể thực hiện tương tự như trên , chỉ cần chỉ định địa chỉ SSH bằng cách sử dụng cú pháp [user@]host:pathhoặc ssh://[user@]host/path.

  1. Tạo kho lưu trữ 'từ xa' bằng cách chạy git init --bare <somepath.git>trên máy chủ được chỉ định (thông qua SSH).

  2. Trong máy tính 1, cách tương tự như đã trình bày trước đó.

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    

    Hoặc nếu bạn thích:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. Trong máy tính 2, một lần nữa giống như phương pháp 1a.


Phương pháp 2: Bạn có thể tạo 'các gói chuyển' lưu trữ một danh sách các xác nhận đã cho vào một tệp.

Thật không may, các lệnh bó không tự động nhớ những gì đã được gói lần trước, vì vậy việc gắn thẻ thủ công hoặc ghi chú là cần thiết. Tôi sẽ chỉ lấy các ví dụ từ hướng dẫn sử dụng git-bundle.

  1. Trong máy tính 1, tạo một gói của toàn bộ chi nhánh:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. Trong máy tính 2, kéo từ gói như thể nó là một kho lưu trữ:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    

Các gói tiếp theo không cần phải đóng gói toàn bộ master- thay vào đó chúng chỉ có thể đóng gói các cam kết mới được thêm last-bundled..mastervào.

  1. Trong máy tính 1, tạo một gói các cam kết mới được thêm vào:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. Giống như trên.


thực ra nó không tệ cho mục đích của tôi, trong git không có gì là "chính" vì mọi kho lưu trữ đều có toàn bộ lịch sử, vì vậy bạn có thể tạo lại nó mỗi khi có điều gì đó tồi tệ
Tutu Kaeen 17/10/18

manual tagging or note-keeping is needed, một tùy chọn trừ khi repo rất lớn là : git bundle create my.bundle --all, nó nên chứa mọi thứ
Birdspider 17/10/18

Tôi thích câu trả lời này hơn vì nó mang tính minh họa hơn mặc dù câu trả lời được chấp nhận và điều này nói lên điều tương tự.
Rystraum

Tầm quan trọng của tùy chọn "trần" là gì?
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
Nó tạo ra một kho lưu trữ chỉ là cơ sở dữ liệu (những gì bạn thường tìm thấy trong .git/thư mục ẩn), không có 'cây làm việc' (các tệp có thể chỉnh sửa). Đây là hình thức ưa thích cho các kho lưu trữ mà bạn git push.
grawity

20

git bundle create

Một trong những phương pháp là sử dụng bộ nhớ ngoài để trao đổi dữ liệu giữa các kho lưu trữ là gói git . Bằng cách này, bạn chỉ có các tệp duy nhất cho mỗi lần chuyển, không phải kho lưu trữ Git trung gian.

Mỗi "git đẩy" biến thành việc tạo một tệp, "git fetch" tìm nạp mọi thứ từ tệp đó.

Phiên demo

Tạo kho lưu trữ đầu tiên và thực hiện "đẩy" đầu tiên

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"Nhân bản" vào kho lưu trữ thứ hai (tức là máy tính thứ hai):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1

Thực hiện một số thay đổi và "đẩy" chúng sang tệp bó khác:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"kéo" thay đổi vào kho lưu trữ đầu tiên:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2

Không giống như gói đầu tiên, gói thứ hai chỉ chứa một phần lịch sử Git và không thể nhân bản trực tiếp:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects

Có một bất lợi trong việc sử dụng các gói mà bạn cần chỉ định thủ công phạm vi cam kết mà mỗi gói nên chứa. Không giống như git push, git bundlekhông theo dõi những gì trong gói trước, bạn cần điều chỉnh thủ công refs/remotes/origin/masterhoặc các gói sẽ lớn hơn mức có thể.


Đừng quên đề cập đến --allcờ để có được mọi thứ. Nếu repo đủ nhỏ thì đây là quy trình đơn giản nhất vì bạn chỉ cần chuyển mọi thứ mọi lúc! Chỉ cần không làm mất thẻ nhớ - có lẽ là vấn đề bảo mật lớn nhất!
Philip Oakley

7

Trước tiên bạn cần cài đặt Git . Sau đó, để tạo một kho lưu trữ mới, hãy chạy trong thư mục mà bạn đã sao chép:

git init

Sau đó, bạn có thể thêm các tệp bạn muốn kiểm soát phiên bản bằng cách git add(thêm -acho tất cả các tệp) và bắt đầu thực hiện các thay đổi ( git commit).

Bạn không cần phải đẩy đến bất kỳ điều khiển từ xa nào, vì bạn có thể làm việc trên lịch sử địa phương của mình ( git log).

Để biết thêm thông tin, kiểm tra:


Đẩy / kéo mà không cần internet

Sử dụng git pushlệnh, có thể đẩy SSH (sử dụng kết nối cục bộ, mạng nội bộ):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server

hoặc đẩy vào thư mục:

git push /mnt/usb/my_repo

Điều này giả sử bạn có hai bản sao của kho lưu trữ của bạn.

Tương tự với kéo, ví dụ

git pull /mnt/usb/my_repo

Để áp dụng các bản vá, bạn có thể sử dụng patchlệnh hoặc git apply.

Xem: Tạo tệp vá hoặc tệp diff từ kho git và áp dụng nó cho kho lưu trữ git khác .


5

Bạn cũng có thể sử dụng Git cục bộ. Sau đó, các cam kết của bạn chỉ được lưu trữ cục bộ và bạn vẫn có quyền kiểm soát phiên bản với nó (và có thể diff / merge, v.v.), nhưng bạn không thể truy cập kho lưu trữ từ bất kỳ máy tính nào khác.

Bạn có thể bắt đầu một kho lưu trữ Git cục bộ bằng cách chạy git inittrong thư mục cục bộ của bạn. Theo mô tả ở đây .


3
mà tôi biết, nhưng tôi muốn làm việc trên một máy tính khác và áp dụng nó vào các tệp trên máy chủ không có truy cập internet
Tutu Kaeen

2
@TutuKaeen Tôi thấy không có gì sai khi có kho lưu trữ trên ổ đĩa flash và chỉ cần sao chép / đồng bộ hóa nó vào ổ cứng của các máy tính khác nhau. Tuy nhiên, "máy chủ không có truy cập internet" nghe có vẻ lạ, mục tiêu của máy chủ là cung cấp dịch vụ, thông thường dịch vụ này liên quan đến kết nối mạng (nhưng thực tế không phải lúc nào cũng vậy).
AnonymousLurker

2
@dhae - Vui lòng dành chút thời gian để cung cấp thêm chi tiết về cách sử dụng Git cục bộ. Chỉ cho thấy nó có thể được thực hiện không phải là hữu ích của một câu trả lời.
Ramhound

2
@anonymousLurker phục vụ là phục vụ dữ liệu cho mạng kín trong tổ chức rất quan trọng. Nó chỉ không phục vụ bất cứ điều gì cho internet rộng lớn, vì dữ liệu rất tinh vi và chỉ dành cho nhân viên.
Tutu Kaeen

1
@TutuKaeen: Nếu nó có bất kỳ truy cập mạng, bạn luôn có thể chạy máy chủ Git của riêng bạn thông qua SSH. Có nhiều thứ với Git hơn là GitHub.
grawity
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.