Làm thế nào để tôi sao chép vào một thư mục không trống?


573

Tôi có thư mục A với các tệp phù hợp với thư mục B. Thư mục A có thể có các tệp cần thiết khác. Thư mục B là một repo git.

Tôi muốn sao chép thư mục B sang thư mục A nhưng git-clone sẽ không cho phép tôi vì thư mục này không trống.

Tôi đã hy vọng nó sẽ sao chép .git và vì tất cả các tệp phù hợp với tôi có thể đi từ đó?

Tôi không thể sao chép vào một thư mục trống vì tôi có các tệp trong thư mục A không có trong thư mục B và tôi muốn giữ chúng.

Sao chép .git không phải là một tùy chọn vì tôi muốn giới thiệu đẩy / kéo và tôi không muốn thiết lập chúng theo cách thủ công.

Có cách nào để làm điều này?

Cập nhật: Tôi nghĩ rằng điều này hoạt động, bất cứ ai có thể nhìn thấy bất kỳ vấn đề? ->

cd a
git clone --no-hardlinks --no-checkout ../b a.tmp 
mv a.tmp/.git .
rm -rf a.tmp
git unstage # apparently git thinks all the files are deleted if you don't do this

5
có lẽ bạn có thể thay đổi câu trả lời được chấp nhận?
Bastiaan Quast

Câu trả lời:


724

Điều này làm việc cho tôi:

git init
git remote add origin PATH/TO/REPO
git fetch
git reset origin/master  # Required when the versioned files existed in path before "git init" of this repo.
git checkout -t origin/master

LƯU Ý: -t sẽ thiết lập nhánh ngược dòng cho bạn, nếu đó là những gì bạn muốn và nó thường là.


70
Điều này không hoạt động trong một thư mục không trống khi các tệp đến đã tồn tại (như câu hỏi ban đầu mô tả). Nhưng nếu bạn git reset origin/mastersau git fetchđó, nó sẽ hoạt động (cũng bảo toàn bất kỳ thay đổi cục bộ nào).
Araxia

8
gây tử vong: Không thể cập nhật đường dẫn và chuyển sang nhánh 'chủ' cùng một lúc.
Arnold Roa

7
Câu trả lời này không hiệu quả với tôi. Khi tôi làm git checkout ...git phàn nàn rằng tất cả các tập tin của tôi sẽ bị ghi đè và tôi nên di chuyển chúng trước. Khi tôi thực hiện `git reset origin / master /`, đầu tiên lệnh checkout sẽ phàn nàn rằng một nhánh có tên master đã tồn tại.
Saskia

4
git checkout masterlà một bước cuối cùng đủ cho tôi.
yoyo

16
Tất cả các bước hoạt động hoàn hảo nhưng bước cuối cùng đã giúp tôi : fatal: A branch named 'master' already exists. Tôi nghĩ rằng tôi không thực sự cần nó.
Shadi

164

Trong các lệnh shell sau đây existing-dirlà một thư mục có nội dung khớp với các tệp được theo dõi trong repo-to-clonekho git.

# Clone just the repository's .git folder (excluding files as they are already in
# `existing-dir`) into an empty temporary directory
git clone --no-checkout repo-to-clone existing-dir/existing-dir.tmp # might want --no-hardlinks for cloning local repo

# Move the .git folder to the directory with the files.
# This makes `existing-dir` a git repo.
mv existing-dir/existing-dir.tmp/.git existing-dir/

# Delete the temporary directory
rmdir existing-dir/existing-dir.tmp
cd existing-dir

# git thinks all files are deleted, this reverts the state of the repo to HEAD.
# WARNING: any local changes to the files will be lost.
git reset --hard HEAD

5
Tôi cần phải làm git reset --hard HEADhoặc nó sẽ không từ bỏ các tập tin "đã xóa".
Dimitar

18
git reset HEADlàm việc tốt cho tôi git reset --hard HEADphá hủy mọi thay đổi trong tệp của bạn, vì vậy nếu chúng không hoàn toàn giống với các tệp trong kho lưu trữ, bạn không nên làm điều đó.
Tgr

1
git reset HEADdường như không có bất kỳ ảnh hưởng nào đối với tôi. git reset --hard HEADkhông - nhưng điều đó làm mất bất kỳ thay đổi nào bạn đã thực hiện đối với các tệp. Có một giải pháp tốt hơn?
Jacob Dorman

1
Câu trả lời của @ Casey - git init / remote add / fetch / checkout - sạch hơn và đơn giản hơn và không yêu cầu bất kỳ thư mục tạm thời nào.
yoyo

1
Câu trả lời của @ Casey không hiệu quả với tôi khi đã có các tệp trong các thư mục cần duy trì nhưng không có trong repo git. Điều này hữu ích để cập nhật cấu hình sau khi chạy tập lệnh cài đặt nơi tệp và thư mục được tạo nhưng bạn cần cập nhật / thêm tệp trên đầu trang đã cài đặt.
soulston

104

Một sửa đổi nhỏ cho một trong những câu trả lời phù hợp với tôi:

git init
git remote add origin PATH/TO/REPO
git pull origin master

để bắt đầu làm việc trên nhánh chính ngay lập tức.


1
phải thiết lập lại ĐẦU - để xóa thư mục hiện có bẩn, mà không xóa các tệp không liên quan được chỉ định trong gitignore
Ray Foss

1
Đây là một trong những thực sự làm việc cho tôi, trái ngược với câu trả lời của @ cmcginty.
chắc chắn

4
Điều này không hoàn toàn tương đương với một git-clone - thứ còn thiếu là thông tin ngược dòng cho nhánh chính. Điều này có thể được sửa chữa bằng cách thêm git branch --set-upstream-to=origin/master master.
Slaven Rezic

Phiên bản này hoạt động với tôi, chỉ cần thực hiện thiết lập lại git - ĐẦU CHÍNH
Frédéric Klee

29

Cảnh báo - điều này có khả năng ghi đè lên các tập tin.

git init     
git remote add origin PATH/TO/REPO     
git fetch     
git checkout -t origin/master -f

Được sửa đổi từ câu trả lời của @ cmcginty - không có -f nó không hoạt động với tôi


Chắc chắn bạn cần kiểm tra tất cả các tập tin sau này với git checkout .?
Chris Stryczynski

25

Đây là những gì tôi đã làm khi tôi gặp vấn đề tương tự (ít nhất tôi nghĩ đó là cùng một vấn đề). Tôi vào thư mục A và chạy git init.

Vì tôi không muốn các tệp trong thư mục A được theo dõi bởi git, tôi đã chỉnh sửa .gitignore và thêm các tệp hiện có vào nó. Sau này tôi chạy git remote add origin '<url>' && git pull origin masteret voíla, B được "nhân bản" thành A mà không có một tiếng nấc nào.


2
Kỹ thuật này không hoạt động trong một thư mục không trống khi các tệp đến đã tồn tại (như câu hỏi ban đầu mô tả).
Araxia

11

Tôi đã sử dụng điều này một vài phút trước đây, yêu cầu các lệnh có khả năng phá hủy ít nhất:

cd existing-dir
git clone --bare repo-to-clone .git
git config --unset core.bare
git remote rm origin
git remote add origin repo-to-clone
git reset

Và Voila!


10

Một công thức đơn giản khác dường như hoạt động tốt với tôi:

git clone --bare $URL .git
git config core.bare false

Trường hợp sử dụng chính của tôi để kiểm tra thư mục chứa các tệp hiện có là kiểm soát các dotfiles Unix của tôi bằng Git. Trên một tài khoản mới, thư mục chính sẽ có một số tệp trong đó, thậm chí có thể là những tệp tôi muốn lấy từ Git.


1
Các kho lưu trữ trần được thiết lập hơi khác một chút và trong khi nó không hoạt động, tôi không khuyến nghị. :)
ThorSummoner 17/2/2016

1
Bạn có thể cụ thể hơn không? Có gì khác nhau?
Ken Williams

1
Chỉ có hai điểm khác biệt: 1.) .git/configTệp chỉ ra rằng repos trống. 2.) Các tệp thường được lưu trữ .gitđược lưu trữ tại thư mục gốc (mà bạn đã gọi .git)
mozey

4
Đó là chính xác những thay đổi nhân bản .gitvà thiết lập core.baređể falsesẽ chăm sóc, vì vậy tôi vẫn cảm thấy tốt về phương pháp này.
Ken Williams

10

Điều này làm việc cho tôi:

cd existing_folder
git init
git remote add origin path_to_your_repo.git
git add .
git commit
git push -u origin master

6

Tôi gặp vấn đề tương tự với một thư mục web Apache mới (tài khoản được tạo bằng WHM) mà tôi dự định sử dụng làm máy chủ web dàn dựng. Tôi cần ban đầu sao chép dự án mới của mình với cơ sở mã ở đó và định kỳ triển khai các thay đổi bằng cách lấy từ kho lưu trữ.

Vấn đề là tài khoản đã chứa các tệp máy chủ web như:

.bash_history
.bash_logout
.bash_profile
.bashrc
.contactemail
.cpanel/
...

... rằng tôi không muốn xóa hoặc cam kết với kho lưu trữ của mình. Tôi cần họ ở lại đó và không bị theo dõi.

Tôi đã làm gì:

Tôi đã đi đến thư mục web của mình (current_folder):

cd /home/existing_folder

và sau đó:

git init
git remote add origin PATH/TO/REPO
git pull origin master
git status

Nó hiển thị (như mong đợi) một danh sách gồm nhiều tệp không được phân loại - những tệp đã tồn tại ban đầu từ tài khoản web cPanel của tôi.

Sau đó, nhờ bài viết này , tôi mới thêm danh sách các tệp đó vào:

**.git/info/exclude**

Tệp này, gần giống như .gitignoretệp, cho phép bạn bỏ qua các tệp khỏi bị dàn dựng. Sau này, tôi không có gì để cam kết trong thư mục .git / - nó hoạt động như một cá nhân .gitignoremà không ai khác có thể nhìn thấy.

Bây giờ kiểm tra git statustrả về:

On branch master
nothing to commit, working tree clean

Bây giờ tôi có thể triển khai các thay đổi cho máy chủ web này bằng cách chỉ cần lấy từ kho git của mình. Hy vọng điều này sẽ giúp một số nhà phát triển web dễ dàng tạo ra một máy chủ dàn dựng.


5

Đây là những gì tôi đang làm:

git clone repo /tmp/folder
cp -rf /tmp/folder/.git /dest/folder/
cd /dest/folder
git checkout -f master

4

Có thể tôi đã hiểu nhầm câu hỏi của bạn, nhưng sẽ không đơn giản hơn nếu bạn sao chép / di chuyển các tệp từ A sang git repo B và thêm những thứ cần thiết bằng git add ?

CẬP NHẬT: Từ tài liệu git:

Nhân bản vào một thư mục hiện có chỉ được phép nếu thư mục trống.

NGUỒN: http://git-scm.com/docs/git-clone


2
Không, chủ sở hữu và các tập tin có thể tùy ý. Đây là một tình huống với nhiều nhà phát triển. Tất cả chúng ta đều có các thư mục hiện có và chỉ có một thư mục hiện có kiểm tra git. Tất cả chúng ta phần lớn có cùng một tập hợp con các tệp vì vậy chúng tôi muốn các nhà phát triển khác có thể sao chép trong khi giữ lại các tệp của họ. Và nó nên được thanh lịch và thuận tiện nhất có thể.
Dale Forester

Thành thật mà nói, tôi không thấy quan điểm phát triển trong điều kiện như vậy. Bạn không thể sử dụng các chi nhánh và hợp nhất các hoạt động? Hoặc có kho lưu trữ phụ với các phụ thuộc bên ngoài? Tại sao bạn muốn dựa vào một "kiểm tra git" duy nhất?
Roberto Aloi

5
Một "kiểm tra git duy nhất" không phải là điểm của toàn bộ thử thách. Chỉ là đây là như vậy và chúng ta cần một cách để tiến về phía trước. Tôi đã cập nhật câu hỏi ban đầu với một giải pháp có vẻ như đang hoạt động. Tôi đánh giá cao thông tin phản hồi, mặc dù.
Dale Forester

3
Có rất nhiều trường hợp hợp pháp cho việc này - Tôi có một cây thư mục phức tạp phải được thiết lập TRƯỚC KHI nguồn dự án của tôi có thể được thiết lập và cây thư mục đó chứa các tác phẩm được cấp phép không thể được lưu trữ trên GitHub.
BrainSlugs83

3

Tôi đang tìm kiếm một cái gì đó tương tự, và đây là những gì tôi nghĩ ra:

Tình huống của tôi là một nơi tôi có một cây web đang hoạt động và tôi đã cố gắng tạo một kho lưu trữ từ xa cho nó mà không di chuyển bất kỳ tệp nào trong cây web hiện tại. Đây là những gì tôi đã làm:

  1. Đi đến cây web và chạy git init
  2. Đi đến vị trí dự định của kho lưu trữ và chạy: git clone --bare /path/to/web/repo
  3. Chỉnh sửa tập tin cấu hình trong repo từ xa của tôi và loại bỏ [remote "origin"]phần.
  4. Thêm một [remote "origin"]phần vào .git / config trong cây web trỏ đến repo từ xa mới.

Tôi thích công thức này rất nhiều.
ngày

git clone --baređây là thừa và có mạch. Tại sao không chỉ git remote add origin <URL>ở nơi đầu tiên?
Araxia

3

đây là công việc đối với tôi nhưng bạn nên hợp nhất các tệp kho lưu trữ từ xa vào các tệp cục bộ:

git init
git remote add origin url-to-git
git branch --set-upstream-to=origin/master master
git fetch
git status

1

Tôi thích câu trả lời của Dale và tôi cũng đã thêm

git clone --depth 2 --no-checkout repo-to-clone existing-dir/existing-dir.tmp
git branch dev_new214
git checkout dev_new214
git add .
git commit
git checkout dev
git merge dev_new214

Độ sâu nông tránh được rất nhiều cam kết phát triển sớm. Chi nhánh mới đã cho chúng tôi một lịch sử hình ảnh tốt rằng có một số mã mới từ máy chủ này được đặt vào. Đó là chi nhánh sử dụng hoàn hảo theo ý kiến ​​của tôi. Tôi cảm ơn sự hiểu biết tuyệt vời của tất cả những người đã đăng ở đây.


0

Tôi gặp vấn đề tương tự khi cố gắng sao chép vào c / code

Nhưng thư mục này chứa một loạt các dự án.

Tôi đã tạo một thư mục mới trong c / code / newproject và ánh xạ bản sao của tôi vào thư mục này.

git cho máy tính để bàn sau đó hỏi người dùng của tôi và sau đó nhân bản tốt.

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.