Làm cách nào để nhập kho Git hiện có vào kho khác?


476

Tôi có kho lưu trữ Git trong thư mục có tên là XXX và tôi có kho lưu trữ Git thứ hai có tên là YYY .

Tôi muốn nhập kho lưu trữ XXX vào kho lưu trữ YYY dưới dạng thư mục con có tên ZZZ và thêm tất cả lịch sử thay đổi của XXX vào YYY .

Cấu trúc thư mục trước:

├── XXX
│   ├── .git
│   └── (project files)
└── YYY
    ├── .git
    └── (project files)

Cấu trúc thư mục sau:

YYY
├── .git  <-- This now contains the change history from XXX
├──  ZZZ  <-- This was originally XXX
│    └── (project files)
└──  (project files)

Điều này có thể được thực hiện hay tôi phải sử dụng các mô-đun phụ?


2
Trên Github giờ đây có thể thực hiện việc này từ giao diện web khi bạn tạo một repo mới
bgcode

Câu trả lời:


430

Có lẽ cách đơn giản nhất là kéo các công cụ XXX vào một nhánh trong YYY và sau đó hợp nhất nó thành chủ:

YYY :

git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master
mkdir ZZZ
git mv stuff ZZZ/stuff                      # repeat as necessary for each file/dir
git commit -m "Moved stuff to ZZZ"
git checkout master                
git merge ZZZ --allow-unrelated-histories   # should add ZZZ/ to master
git commit
git remote rm other
git branch -d ZZZ                           # to get rid of the extra branch before pushing
git push                                    # if you have a remote, that is

Tôi thực sự chỉ cần thử điều này với một vài repos của tôi và nó hoạt động. Không giống như câu trả lời của Jorg, nó sẽ không cho phép bạn tiếp tục sử dụng repo khác, nhưng tôi không nghĩ bạn đã chỉ định điều đó.

Lưu ý: Vì điều này ban đầu được viết vào năm 2009, git đã thêm hợp nhất cây con được đề cập trong câu trả lời dưới đây. Tôi có thể sẽ sử dụng phương pháp đó ngày hôm nay, mặc dù tất nhiên phương pháp này vẫn hoạt động.


1
Cảm ơn. Tôi đã sử dụng một phiên bản sửa đổi một chút về kỹ thuật của bạn: Tôi đã tạo một nhánh 'dàn dựng' trên XXX nơi tôi đã tạo thư mục ZZZ và di chuyển 'nội dung' vào đó. Sau đó, tôi đã hợp nhất XXX vào YYY.
Vijay Patel

1
Nó hiệu quả tuyệt vời đối với tôi. Những thay đổi duy nhất tôi đã thực hiện là: 1) "git chi nhánh -d ZZZ" trước khi đẩy vì tôi không muốn chi nhánh tạm thời này treo xung quanh. 2) "git đẩy" đã gây ra lỗi cho tôi: "Không có giới thiệu chung và không được chỉ định; không làm gì cả. Có lẽ bạn nên chỉ định một nhánh như 'chủ'." (Nguồn gốc mà tôi đang đẩy đến là một kho lưu trữ trống rỗng.) Nhưng "git đẩy --all" hoạt động như một nhà vô địch.
CrazyPyro

1
Tôi muốn kết thúc chỉ với thư mục ZZZ cộng với lịch sử trong repo YYY: Tôi muốn xóa repo XXX gốc và nhánh ZZZ trong repo YYY. Tôi thấy việc xóa chi nhánh ZZZ khi @CrazyPyro đề nghị xóa lịch sử - để giữ cho nó, tôi đã hợp nhất chi nhánh ZZZ thành chủ trước khi xóa.
Oli Studholme

4
@SebastianBlask Tôi chỉ loay hoay với điều này với hai trong số các repos của mình và nhận ra rằng có một bước còn thiếu mà không ai có thể nhận thấy, mặc dù tôi đã nhận được thông tin này trong nhiều năm. :-) Tôi đã đề cập đến việc hợp nhất nó thành chủ, nhưng thực tế không hiển thị nó. Chỉnh sửa nó ngay bây giờ ...
ebneter

2
bạn có thể thêm một cái gì đó như thế này, khi di chuyển tệp vào thư mục con của bạn: git mv $(ls|grep -v <your foldername>) <your foldername>/ Điều này sẽ sao chép tất cả các tệp và thư mục vào thư mục mới của bạn
serup

367

Nếu bạn muốn giữ lại lịch sử cam kết chính xác của kho lưu trữ thứ hai và do đó cũng giữ được khả năng dễ dàng hợp nhất các thay đổi ngược dòng trong tương lai thì đây là phương pháp bạn muốn. Nó dẫn đến lịch sử chưa sửa đổi của cây con được nhập vào repo của bạn cộng với một cam kết hợp nhất để di chuyển kho lưu trữ đã hợp nhất sang thư mục con.

git remote add XXX_remote <path-or-url-to-XXX-repo>
git fetch XXX_remote
git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master
git read-tree --prefix=ZZZ/ -u XXX_remote/master
git commit -m "Imported XXX as a subtree."

Bạn có thể theo dõi các thay đổi ngược dòng như vậy:

git pull -s subtree XXX_remote master

Git tự tìm ra gốc rễ ở đâu trước khi thực hiện hợp nhất, vì vậy bạn không cần chỉ định tiền tố cho các lần hợp nhất tiếp theo.

Các nhược điểm là trong lịch sử sáp nhập các tập tin là không tiền tố (không phải trong một thư mục con). Kết quả là git log ZZZ/asẽ cho bạn thấy tất cả các thay đổi (nếu có) ngoại trừ những thay đổi trong lịch sử đã hợp nhất. Bạn có thể làm:

git log --follow -- a

nhưng điều đó sẽ không cho thấy những thay đổi khác trong lịch sử hợp nhất.

Nói cách khác, nếu bạn không thay đổi ZZZcác tệp trong kho lưu trữ XXX, thì bạn cần chỉ định --followvà một đường dẫn không được trộn. Nếu bạn thay đổi chúng trong cả hai kho lưu trữ, thì bạn có 2 lệnh, không có lệnh nào hiển thị tất cả các thay đổi.

Phiên bản Git trước 2.9 : Bạn không cần chuyển --allow-unrelated-historiestùy chọn sang git merge.

Phương pháp trong câu trả lời khác sử dụng read-treevà bỏ qua merge -s oursbước này thực sự không khác gì sao chép các tệp bằng cp và cam kết kết quả.

Nguồn gốc là từ bài viết trợ giúp "Subtree Merge" của github . Và một liên kết hữu ích khác .


9
điều này dường như không được lưu giữ lịch sử ... nếu tôi thực hiện git logbất kỳ tệp nào tôi đã tải vào, tôi chỉ thấy một cam kết hợp nhất duy nhất và không có gì từ kiếp trước trong repo khác? Git 1.8.0
Anentropic

8
aha nếu tôi sử dụng đường dẫn cũ của tệp đã nhập, tức là bỏ qua thư mục con được nhập vào, thì nhật ký git sẽ cung cấp cho tôi lịch sử cam kết, ví dụ git log -- myfilethay vìgit log -- rack/myfile
Anentropic

2
@FrancescoFrassinelli, không phải là mong muốn sao? Đưa lịch sử vào là một tính năng của phương pháp này.
patrickvacek

4
@FrancescoFrassinelli, nếu bạn không muốn lịch sử, tại sao không làm một bản sao thông thường? Tôi đang cố gắng tìm ra điều gì sẽ lôi kéo bạn đến với phương pháp này nếu không phải vì lịch sử - đó là lý do duy nhất tôi sử dụng phương pháp này!
patrickvacek

7
Kể từ Git 2.9, bạn cần tùy chọn --allow-unrelated-historieskhi thực hiện hợp nhất.
stuXnet

112

git-subtreelà một tập lệnh được thiết kế cho chính xác trường hợp sử dụng này để hợp nhất nhiều kho lưu trữ thành một trong khi lưu giữ lịch sử (và / hoặc tách lịch sử của các cây con, mặc dù điều đó dường như không liên quan đến câu hỏi này). Nó được phân phối như một phần của cây git kể từ khi phát hành 1.7.11 .

Để hợp nhất một kho lưu trữ <repo>khi sửa đổi <rev>làm thư mục con <prefix>, hãy sử dụng git subtree addnhư sau:

git subtree add -P <prefix> <repo> <rev>

git-Subree thực hiện chiến lược hợp nhất cây con theo cách thân thiện hơn với người dùng.

Đối với trường hợp của bạn, bên trong kho YYY, bạn sẽ chạy:

git subtree add -P ZZZ /path/to/XXX.git master

Các nhược điểm là trong lịch sử sáp nhập các tập tin là không tiền tố (không phải trong một thư mục con). Kết quả là git log ZZZ/asẽ cho bạn thấy tất cả các thay đổi (nếu có) ngoại trừ những thay đổi trong lịch sử đã hợp nhất. Bạn có thể làm:

git log --follow -- a

nhưng điều đó sẽ không cho thấy những thay đổi khác trong lịch sử hợp nhất.

Nói cách khác, nếu bạn không thay đổi ZZZcác tệp trong kho lưu trữ XXX, thì bạn cần chỉ định --followvà một đường dẫn không được trộn. Nếu bạn thay đổi chúng trong cả hai kho lưu trữ, thì bạn có 2 lệnh, không có lệnh nào hiển thị tất cả các thay đổi.

Thêm về nó ở đây .


4
Nếu bạn có một thư mục để hợp nhất thay vì một kho lưu trữ hoặc điều khiển từ xa,git subtree add -P name-of-desired-prefix ~/location/of/git/repo-without-.git branch-name
Tatsh

2
Trải nghiệm của Noob: git (phiên bản 2.9.0.windows.1) phản hồi "fatal: đối số mơ hồ 'ĐẦU': sửa đổi không xác định hoặc đường dẫn không có trong cây làm việc" khi tôi đã thử điều này trong kho lưu trữ mới được khởi tạo, cục bộ, không trần, Nhưng nó hoạt động tốt sau khi tôi thực sự có kho lưu trữ mới, tức là sau khi thêm một tệp đơn giản và cam kết theo cách thông thường.
Stein

Làm việc đẹp cho kịch bản của tôi.
Johnny Utahh

Ồ điều này thật tuyệt vời.
dwjohnston

Tôi đã sử dụng đề xuất @Tatsh và nó hoạt động với tôi
Carmine Tambascia

49

Có một ví dụ nổi tiếng về điều này trong kho lưu trữ Git, được gọi chung trong cộng đồng Git là " sự hợp nhất tuyệt vời nhất từng có " (sau dòng tiêu đề Linus Torvalds được sử dụng trong e-mail đến danh sách gửi thư Git mô tả điều này hợp nhất). Trong trường hợp này, gitkGUI Git hiện là một phần của Git thích hợp, thực sự được sử dụng để trở thành một dự án riêng biệt. Linus quản lý để hợp nhất kho lưu trữ đó vào kho Git theo cách

  • nó xuất hiện trong kho Git như thể nó luôn được phát triển như một phần của Git,
  • tất cả lịch sử được giữ nguyên và
  • nó vẫn có thể được phát triển độc lập trong kho lưu trữ cũ của nó, với những thay đổi đơn giản là git pulled.

Email chứa các bước cần thiết để tái tạo, nhưng nó không dành cho người yếu tim: đầu tiên, Linus đã viết Git, vì vậy anh ta có thể biết nhiều hơn về nó so với bạn và tôi, và thứ hai, điều này đã gần 5 năm trước và Git đã được cải thiện đáng kể kể từ đó, vì vậy có lẽ bây giờ nó dễ dàng hơn nhiều.

Cụ thể, tôi đoán ngày nay người ta sẽ sử dụng một mô hình con gitk, trong trường hợp cụ thể đó.


3
BTW. chiến lược được sử dụng cho các lần hợp nhất tiếp theo (nếu có) được gọi là hợp nhất cây con và có git-subtreecông cụ của bên thứ ba có thể giúp bạn với điều này: github.com/apenwarr/git-subtree
Jakub Narębski

Cảm ơn, tôi đã quên điều đó. Các subtreechiến lược hợp nhất, đặc biệt là kết hợp với các git-subtreecông cụ là một tốt đẹp, có thể thay thế thậm chí vượt trội so với các môđun con.
Jörg W Mittag

12

Cách đơn giản để làm điều đó là sử dụng git format-patch.

Giả sử chúng ta có 2 kho git foobar .

foo chứa:

  • foo.txt
  • .git

thanh chứa:

  • bar.txt
  • .git

và chúng tôi muốn kết thúc với foo chứa lịch sử thanh và các tệp này:

  • foo.txt
  • .git
  • foobar / bar.txt

Vì vậy, để làm điều đó:

 1. create a temporary directory eg PATH_YOU_WANT/patch-bar
 2. go in bar directory
 3. git format-patch --root HEAD --no-stat -o PATH_YOU_WANT/patch-bar --src-prefix=a/foobar/ --dst-prefix=b/foobar/
 4. go in foo directory
 5. git am PATH_YOU_WANT/patch-bar/*

Và nếu chúng ta muốn viết lại tất cả các cam kết thông báo từ thanh chúng ta có thể làm, ví dụ như trên Linux:

git filter-branch --msg-filter 'sed "1s/^/\[bar\] /"' COMMIT_SHA1_OF_THE_PARENT_OF_THE_FIRST_BAR_COMMIT..HEAD

Điều này sẽ thêm "[bar]" vào đầu mỗi thông điệp cam kết.


Nếu kho lưu trữ ban đầu chứa các nhánh và sáp nhập, git amcó thể sẽ thất bại.
Adam Monsen

1
Gotcha nhỏ: git am tước bất cứ thứ gì [ ]từ thông điệp cam kết. Vì vậy, bạn nên sử dụng một điểm đánh dấu khác với[bar]
HRJ

Không làm việc cho tôi. Có "lỗi: foobar / mySubDir / test_host1: không tồn tại trong chỉ mục. Bản sao của bản vá bị lỗi được tìm thấy trong: /home/myuser/src/proj/.git/rebase-apply/patch Khi bạn đã giải quyết vấn đề này , chạy "git am --continue". Đây là sau khi áp dụng 11 bản vá (trong số 60).
oligofren

1
Blog này có một câu trả lời tương tự cho một câu hỏi hơi khác (chỉ di chuyển các tệp được chọn).
Jesse Glick

Tôi thấy một nhược điểm, tất cả các cam kết được thêm vào ĐẦU của kho đích.
CSchulz

8

Hàm này sẽ sao chép repo từ xa vào thư mục repo cục bộ, sau khi hợp nhất tất cả các xác nhận sẽ được lưu, git logsẽ hiển thị các cam kết ban đầu và các đường dẫn thích hợp:

function git-add-repo
{
    repo="$1"
    dir="$(echo "$2" | sed 's/\/$//')"
    path="$(pwd)"

    tmp="$(mktemp -d)"
    remote="$(echo "$tmp" | sed 's/\///g'| sed 's/\./_/g')"

    git clone "$repo" "$tmp"
    cd "$tmp"

    git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

    cd "$path"
    git remote add -f "$remote" "file://$tmp/.git"
    git pull "$remote/master"
    git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
    git remote remove "$remote"
    rm -rf "$tmp"
}

Cách sử dụng:

cd current/package
git-add-repo https://github.com/example/example dir/to/save

Nếu thực hiện một số thay đổi, bạn thậm chí có thể di chuyển tệp / thư mục của repo đã hợp nhất vào các đường dẫn khác nhau, ví dụ:

repo="https://github.com/example/example"
path="$(pwd)"

tmp="$(mktemp -d)"
remote="$(echo "$tmp" | sed 's/\///g' | sed 's/\./_/g')"

git clone "$repo" "$tmp"
cd "$tmp"

GIT_ADD_STORED=""

function git-mv-store
{
    from="$(echo "$1" | sed 's/\./\\./')"
    to="$(echo "$2" | sed 's/\./\\./')"

    GIT_ADD_STORED+='s,\t'"$from"',\t'"$to"',;'
}

# NOTICE! This paths used for example! Use yours instead!
git-mv-store 'public/index.php' 'public/admin.php'
git-mv-store 'public/data' 'public/x/_data'
git-mv-store 'public/.htaccess' '.htaccess'
git-mv-store 'core/config' 'config/config'
git-mv-store 'core/defines.php' 'defines/defines.php'
git-mv-store 'README.md' 'doc/README.md'
git-mv-store '.gitignore' 'unneeded/.gitignore'

git filter-branch --index-filter '
    git ls-files -s |
    sed "'"$GIT_ADD_STORED"'" |
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
' HEAD

GIT_ADD_STORED=""

cd "$path"
git remote add -f "$remote" "file://$tmp/.git"
git pull "$remote/master"
git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
git remote remove "$remote"
rm -rf "$tmp"

Thông báo
Đường dẫn thay thế thông qua sed, vì vậy hãy chắc chắn rằng nó di chuyển theo các đường dẫn thích hợp sau khi hợp nhất.
Các --allow-unrelated-historiestham số chỉ tồn tại kể từ khi git> = 2,9.


2
Đối với những người dùng OS X ngoài kia, hãy cài đặt gnu-sedđể git-add-repochức năng hoạt động. Cảm ơn một lần nữa!
ptaylor

7

Dựa trên bài viết này , sử dụng cây con là những gì làm việc cho tôi và chỉ có lịch sử áp dụng được chuyển giao. Đăng ở đây trong trường hợp bất cứ ai cần các bước (đảm bảo thay thế chỗ dành sẵn bằng các giá trị áp dụng cho bạn):

trong kho lưu trữ nguồn của bạn chia thư mục con thành một nhánh mới

git subtree split --prefix=<source-path-to-merge> -b subtree-split-result

trong repo đích của bạn hợp nhất trong nhánh kết quả phân chia

git remote add merge-source-repo <path-to-your-source-repository>
git fetch merge-source-repo
git merge -s ours --no-commit merge-source-repo/subtree-split-result
git read-tree --prefix=<destination-path-to-merge-into> -u merge-source-repo/subtree-split-result

xác minh thay đổi và cam kết của bạn

git status
git commit

Đừng quên

Dọn dẹp bằng cách xóa subtree-split-resultchi nhánh

git branch -D subtree-split-result

Xóa điều khiển từ xa mà bạn đã thêm để tìm nạp dữ liệu từ repo nguồn

git remote rm merge-source-repo


3

Thêm một câu trả lời khác vì tôi nghĩ rằng điều này đơn giản hơn một chút. Việc kéo repo_dest được thực hiện vào repo_to_import và sau đó một url đẩy --set-upflow: repo_dest master được thực hiện.

Phương pháp này đã giúp tôi nhập một số repos nhỏ hơn thành một cái lớn hơn.

Cách nhập: repo1_to_import để repo_dest

# checkout your repo1_to_import if you don't have it already 
git clone url:repo1_to_import repo1_to_import
cd repo1_to_import

# now. pull all of repo_dest
git pull url:repo_dest
ls 
git status # shows Your branch is ahead of 'origin/master' by xx commits.
# now push to repo_dest
git push --set-upstream url:repo_dest master

# repeat for other repositories you want to import

Đổi tên hoặc di chuyển tệp và thư mục vào vị trí mong muốn trong repo gốc trước khi bạn nhập. ví dụ

cd repo1_to_import
mkdir topDir
git add topDir
git mv this that and the other topDir/
git commit -m"move things into topDir in preparation for exporting into new repo"
# now do the pull and push to import

Phương pháp được mô tả tại liên kết sau đây đã truyền cảm hứng cho câu trả lời này. Tôi thích nó vì nó có vẻ đơn giản hơn. Nhưng hãy cẩn thận! Có rồng! https://help.github.com/articles/importing-an-external-git-reposeective git push --mirror url:repo_dest đẩy lịch sử và trạng thái repo cục bộ của bạn đến từ xa (url: repo_dest). NHƯNG nó xóa lịch sử cũ và trạng thái của điều khiển từ xa. Vui vẻ xảy ra! : -E


1

Tôi chỉ muốn nhập một số tệp từ kho lưu trữ khác (XXX) trong trường hợp của mình. Cây con quá phức tạp đối với tôi và các giải pháp khác không hoạt động. Đây là những gì tôi đã làm:

ALL_COMMITS=$(git log --reverse --pretty=format:%H -- ZZZ | tr '\n' ' ')

Điều này cung cấp cho bạn một danh sách được phân tách bằng dấu cách của tất cả các cam kết ảnh hưởng đến các tệp tôi muốn nhập (ZZZ) theo thứ tự ngược lại (bạn có thể phải thêm --follow để ghi lại các đổi tên). Sau đó tôi đã đi vào kho lưu trữ đích (YYY), thêm kho lưu trữ khác (XXX) dưới dạng từ xa, đã tìm nạp từ nó và cuối cùng:

git cherry-pick $ALL_COMMITS

trong đó thêm tất cả các cam kết vào chi nhánh của bạn, do đó bạn sẽ có tất cả các tệp có lịch sử của chúng và có thể làm bất cứ điều gì bạn muốn với chúng như thể chúng luôn ở trong kho lưu trữ này.


1

Xem ví dụ cơ bản trong bài viết này và xem xét ánh xạ như vậy trên các kho lưu trữ:

  • A<-> YYY,
  • B <-> XXX

Sau khi tất cả hoạt động được mô tả trong chương này (sau khi hợp nhất), hãy xóa chi nhánh B-master:

$ git branch -d B-master

Sau đó, đẩy thay đổi.

Nó làm việc cho tôi.


0

Tôi đã ở trong một tình huống mà tôi đang tìm kiếm -s theirsnhưng tất nhiên, chiến lược này không tồn tại. Lịch sử của tôi là tôi đã rẽ nhánh một dự án trên GitHub, và bây giờ vì một số lý do, địa phương của tôi masterkhông thể hợp nhất được upstream/mastermặc dù tôi không có thay đổi cục bộ nào đối với chi nhánh này. (Thực sự không biết chuyện gì đã xảy ra ở đó - Tôi đoán rằng thượng nguồn đã thực hiện một số cú đẩy bẩn phía sau hậu trường, có lẽ vậy?)

Những gì tôi đã làm là

# as per https://help.github.com/articles/syncing-a-fork/
git fetch upstream
git checkout master
git merge upstream/master
....
# Lots of conflicts, ended up just abandonging this approach
git reset --hard   # Ditch failed merge
git checkout upstream/master
# Now in detached state
git branch -d master # !
git checkout -b master   # create new master from upstream/master

Vì vậy, bây giờ tôi masterlại đồng bộ hóa với upstream/master(và bạn có thể lặp lại ở trên cho bất kỳ chi nhánh nào khác mà bạn cũng muốn đồng bộ hóa tương tự).


1
A git reset --hard upstream/mastertrên masterchi nhánh địa phương của bạn sẽ làm công việc. Bằng cách này, bạn không mất conflg chi nhánh địa phương - những thứ như ngược dòng mặc định.
tomekwi

0

Tôi có thể đề xuất một giải pháp khác (thay thế cho git-mô đun con ) cho vấn đề của bạn - công cụ gil (git links)

Nó cho phép mô tả và quản lý các phụ thuộc kho git phức tạp.

Ngoài ra, nó cung cấp một giải pháp cho vấn đề phụ thuộc đệ quy đệ quy git .

Xem xét bạn có các phụ thuộc dự án sau: biểu đồ phụ thuộc kho lưu trữ git mẫu

Sau đó, bạn có thể xác định .gitlinkstệp với mô tả quan hệ kho lưu trữ:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Mỗi dòng mô tả liên kết git theo định dạng sau:

  1. Tên duy nhất của kho lưu trữ
  2. Đường dẫn tương đối của kho lưu trữ (bắt đầu từ đường dẫn của tệp .gitlinks)
  3. Kho lưu trữ Git sẽ được sử dụng trong lệnh git clone Nhánh kho lưu trữ để kiểm tra
  4. Dòng trống hoặc dòng bắt đầu bằng # không được phân tích cú pháp (được coi là nhận xét).

Cuối cùng, bạn phải cập nhật kho lưu trữ mẫu gốc của mình:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

Kết quả là bạn sẽ sao chép tất cả các dự án cần thiết và liên kết chúng với nhau theo một cách thích hợp.

Nếu bạn muốn cam kết tất cả các thay đổi trong một số kho lưu trữ với tất cả các thay đổi trong kho lưu trữ được liên kết con, bạn có thể thực hiện bằng một lệnh duy nhất:

gil commit -a -m "Some big update"

Các lệnh kéo, đẩy hoạt động theo cách tương tự:

gil pull
gil push

Công cụ Gil (git links) hỗ trợ các lệnh sau:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Thông tin thêm về vấn đề phụ thuộc đệ quy git đệ quy .


0

Hãy để tôi sử dụng tên a(thay cho XXXZZZ) và b(thay cho YYY), vì điều đó làm cho mô tả dễ đọc hơn một chút.

Giả sử bạn muốn hợp nhất kho lưu trữ avào b(Tôi giả sử chúng nằm cạnh nhau):

cd a
git filter-repo --to-subdirectory-filter a
cd ..
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a

Đối với điều này bạn không cần git-filter-repocài đặt ( filter-branchđược khuyến khích ).

Một ví dụ về việc hợp nhất 2 kho lưu trữ lớn, đưa một trong số chúng vào thư mục con: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

Thêm về nó ở đây .


-1

Tôi không biết một cách dễ dàng để làm điều đó. Bạn có thể làm điều này:

  1. Sử dụng nhánh bộ lọc git để thêm siêu thư mục ZZZ trên kho lưu trữ XXX
  2. Đẩy nhánh mới vào kho YYY
  3. Hợp nhất nhánh đẩy với thân cây của YYY.

Tôi có thể chỉnh sửa với các chi tiết nếu điều đó nghe hấp dẫn.


-2

Tôi nghĩ bạn có thể làm điều này bằng cách sử dụng 'git mv' và 'git pull'.

Tôi là một git noob công bằng - vì vậy hãy cẩn thận với kho lưu trữ chính của bạn - nhưng tôi chỉ thử điều này trong một thư mục tạm thời và nó dường như hoạt động.

Đầu tiên - đổi tên cấu trúc của XXX để khớp với cách bạn muốn nó trông như thế nào trong YYY:

cd XXX
mkdir tmp
git mv ZZZ tmp/ZZZ
git mv tmp ZZZ

Bây giờ XXX trông như thế này:

XXX
 |- ZZZ
     |- ZZZ

Bây giờ sử dụng 'git pull' để tìm nạp các thay đổi trên:

cd ../YYY
git pull ../XXX

Bây giờ YYY trông như thế này:

YYY
 |- ZZZ
     |- ZZZ
 |- (other folders that already were in YYY)
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.