Làm cách nào để kiểm tra chỉ một tệp từ repo git?
Làm cách nào để kiểm tra chỉ một tệp từ repo git?
Câu trả lời:
Ban đầu, tôi đã đề cập vào năm 2012 git archive
(xem Jared Forsyth 's câu trả lời và Robert Hiệp sĩ ' s câu trả lời ), vì git1.7.9.5 (tháng 3 năm 2012) , Paul Brannan 's câu trả lời :
git archive --format=tar --remote=origin HEAD:path/to/directory -- filename | tar -O -xf -
Nhưng: vào năm 2013, điều đó không còn có thể đối với các URL https://github.com từ xa .
Xem trang cũ " Tôi có thể lưu trữ một kho lưu trữ không? "
Trang hiện tại (2018) " Giới thiệu về lưu trữ nội dung và dữ liệu trên GitHub " khuyên bạn nên sử dụng các dịch vụ của bên thứ ba như GHTorrent hoặc GH Archive .
Vì vậy, bạn cũng có thể đối phó với các bản sao / bản sao địa phương:
Bạn cũng có thể làm như sau nếu bạn có một bản sao cục bộ của kho lưu trữ trần như được đề cập trong câu trả lời này ,
git --no-pager --git-dir /path/to/bar/repo.git show branch:path/to/file >file
Hoặc trước tiên bạn phải sao chép repo, nghĩa là bạn có được toàn bộ lịch sử: - trong repg .git - trong cây làm việc.
git config core.sparsecheckout true
).git/info/sparse-checkout
tập tinĐể đọc lại cây làm việc:
$ git read-tree -m -u HEAD
Bằng cách đó, bạn kết thúc với một cây làm việc bao gồm chính xác những gì bạn muốn (ngay cả khi đó chỉ là một tệp)
Richard Gomes chỉ ( trong các bình luận ) thành " Làm cách nào để sao chép, tìm nạp hoặc kiểm tra thưa thớt một thư mục hoặc danh sách các thư mục từ kho git? "
Hàm bash tránh tải xuống lịch sử, truy xuất một nhánh duy nhất và truy xuất danh sách các tệp hoặc thư mục bạn cần.
git archive
ngay bây giờ.
Trước tiên, sao chép repo với tùy chọn -n, loại bỏ kiểm tra mặc định của tất cả các tệp và tùy chọn --depth 1, có nghĩa là nó chỉ nhận được bản sửa đổi gần đây nhất của mỗi tệp
git clone -n git://path/to/the_repo.git --depth 1
Sau đó kiểm tra chỉ các tập tin bạn muốn như vậy:
cd the_repo
git checkout HEAD name_of_file
-n
cây công việc và chỉ mục kết thúc đồng bộ. Đó là, tất cả nội dung hiển thị như đã xóa. Bạn phải git reset HEAD
hoặc git checkout HEAD file
. Tại thời điểm này cũng rất khó để làm việc với kho lưu trữ trừ khi bạn thực sự hiểu cách hoạt động của git.
rm -rf .git
tập lệnh khác vào tập lệnh của NickMoore sẽ xóa sạch mọi dấu vết của repo nhân bản và có lẽ làm mất đi sự lo lắng của Jefromi về việc sử dụng repo khó sử dụng. Làm cho nó rất hữu ích cho tôi đối với một số ứng dụng, như thử thách của tôi ngày hôm nay là xây dựng một hook hook nhận để cập nhật phiên bản của một hook hook sau nhận khác.
git
không phải là tốt nhất cho loại công việc này). Câu trả lời này cũng có giá trị cho câu hỏi này hoặc câu hỏi phổ biến khác và nhiều câu hỏi khác: thay đổi name_of_file
thành name_of_folder
. Git trong ngày nay (2014) cung cấp các mô hình con cho chủ sở hữu repo cung cấp một số por thân thiện cho người dùng repo.
Nếu bạn đã có một bản sao của git repo, bạn luôn có thể kiểm tra phiên bản của tệp bằng cách git log
tìm ra mã băm (ví dụ 3cdc61015724f9965575ba954c8cd4232c8b42e4) và sau đó bạn chỉ cần gõ:
git checkout hash-id path-to-file
Đây là một ví dụ thực tế:
git checkout 3cdc61015724f9965575ba954c8cd4232c8b42e4 /var/www/css/page.css
path-to-file
là một thư mục và hiện tại HEAD
chứa một số tệp nhất định trong khi target
không, (hoặc ngược lại), điều này sẽ không cập nhật chính xác tệp. Có cách nào để xử lý?
Thông thường không thể tải xuống chỉ một tệp từ git
mà không tải xuống toàn bộ kho lưu trữ như được đề xuất trong câu trả lời đầu tiên. Đó là vì Git không lưu trữ các tệp như bạn nghĩ (như CVS / SVN làm), nhưng nó tạo ra chúng dựa trên toàn bộ lịch sử của dự án.
Nhưng có một số cách giải quyết cho các trường hợp cụ thể. Ví dụ dưới đây với giữ chỗ cho user
, project
, branch
, filename
.
GitHub
wget https://raw.githubusercontent.com/user/project/branch/filename
GitLab
wget https://gitlab.com/user/project/raw/branch/filename
GitWeb
Nếu bạn đang sử dụng Git trên Máy chủ - GitWeb , thì bạn có thể thử ví dụ (thay đổi nó thành đúng đường dẫn):
wget "http://example.com/gitweb/?p=example;a=blob_plain;f=README.txt;hb=HEAD"
GitWeb tại drupalcode.org
Thí dụ:
wget "http://drupalcode.org/project/ads.git/blob_plain/refs/heads/master:/README.md"
googlesource.com
Có một tính năng không có giấy tờ cho phép bạn tải xuống các phiên bản tệp thô được mã hóa base64:
curl "https://chromium.googlesource.com/chromium/src/net/+/master/http/transport_security_state_static.json?format=TEXT" | base64 --decode
Trong các trường hợp khác, hãy kiểm tra xem kho Git của bạn có đang sử dụng bất kỳ giao diện web nào không.
Nếu nó không được sử dụng bất kỳ giao diện web, bạn có thể xem xét để đẩy mã của bạn với các dịch vụ bên ngoài như GitHub , Bitbucket , vv . và sử dụng nó như một tấm gương.
Nếu bạn chưa wget
cài đặt, hãy thử curl -O (url)
thay thế.
wget
câu trả lời tuyệt vời này và sự trở lại đơn giản, cùng với hạnh phúc. Cảm ơn người đàn ông.
kiểm tra git Branch_or_version - đường dẫn / tệp
thí dụ: git checkout HEAD -- main.c
git-checkout
.
Bây giờ chúng ta có thể! Vì đây là kết quả đầu tiên trên google, tôi nghĩ tôi sẽ cập nhật thông tin này lên vị trí mới nhất. Với sự ra đời của git 1.7.9.5, chúng tôi có git archive
lệnh cho phép bạn truy xuất một tệp từ một máy chủ từ xa.
git archive --remote=git://git.foo.com/project.git HEAD:path/in/repo filename | tar -x
Xem câu trả lời đầy đủ tại đây https://stackoverflow.com/a/5324532/290784
github.com
HEAD
hoặc master
không HEAD:directory
.
git archive --remote=git@bitbucket.org:user/repo branch:path/to file | tar -x
Làm việc trong GIT 1.7.2.2
Ví dụ bạn có một từ xa some_remote với các ngành branch1 , branch32
Vì vậy, để kiểm tra một tập tin cụ thể, bạn gọi lệnh này:
git checkout remote/branch path/to/file
như một ví dụ, nó sẽ giống như thế này
git checkout some_remote/branch32 conf/en/myscript.conf
git checkout some_remote/branch1 conf/fr/load.wav
Lệnh kiểm tra này sẽ sao chép toàn bộ cấu trúc tệp conf / en và conf / fr vào thư mục hiện tại nơi bạn gọi các lệnh này (tất nhiên tôi giả sử bạn đã chạy git init tại một số điểm trước đó)
git fetch some_remote
trước, phải không?
Rất đơn giản:
git checkout from-branch-name -- path/to/the/file/you/want
Điều này sẽ không kiểm tra from-branch-name
chi nhánh. Bạn sẽ ở lại trên bất kỳ nhánh nào bạn đang ở và chỉ có tệp duy nhất đó sẽ được kiểm tra từ nhánh được chỉ định.
Đây là phần có liên quan của trang dành cho git-checkout
git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
When <paths> or --patch are given, git checkout does not switch
branches. It updates the named paths in the working tree from the
index file or from a named <tree-ish> (most often a commit). In
this case, the -b and --track options are meaningless and giving
either of them results in an error. The <tree-ish> argument can be
used to specify a specific tree-ish (i.e. commit, tag or tree) to
update the index for the given paths before updating the working
tree.
Hat tip cho Ariejan de Vroom, người đã dạy tôi điều này từ bài đăng trên blog này .
git clone --filter
từ Git 2.19
Tùy chọn này thực sự sẽ bỏ qua việc tìm nạp hầu hết các đối tượng không cần thiết từ máy chủ:
git clone --depth 1 --no-checkout --filter=blob:none \
"file://$(pwd)/server_repo" local_repo
cd local_repo
git checkout master -- mydir/myfile
Máy chủ nên được cấu hình với:
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1
Không có hỗ trợ máy chủ kể từ v2.19.0, nhưng nó đã có thể được kiểm tra cục bộ.
TODO: --filter=blob:none
bỏ qua tất cả các đốm màu, nhưng vẫn tìm nạp tất cả các đối tượng cây. Nhưng trên một repo bình thường, nó sẽ rất nhỏ so với các tệp, vì vậy điều này đã đủ tốt rồi. Đã hỏi tại: https://www.spinics.net/lists/git/msg342006.html Devs trả lời a --filter=tree:0
đang trong công việc để làm điều đó.
Hãy nhớ điều đó --depth 1
đã ngụ ý --single-branch
, xem thêm: Làm cách nào để sao chép một nhánh duy nhất trong Git?
file://$(path)
được yêu cầu để vượt qua git clone
các shenanigans giao thức: Làm thế nào để sao chép một kho lưu trữ git cục bộ với một đường dẫn tương đối?
Các định dạng của --filter
tài liệu trên man git-rev-list
.
Một phần mở rộng đã được thực hiện cho giao thức từ xa Git để hỗ trợ tính năng này.
Tài liệu trên cây Git:
Kiểm tra nó ra
#!/usr/bin/env bash
set -eu
list-objects() (
git rev-list --all --objects
echo "master commit SHA: $(git log -1 --format="%H")"
echo "mybranch commit SHA: $(git log -1 --format="%H")"
git ls-tree master
git ls-tree mybranch | grep mybranch
git ls-tree master~ | grep root
)
# Reproducibility.
export GIT_COMMITTER_NAME='a'
export GIT_COMMITTER_EMAIL='a'
export GIT_AUTHOR_NAME='a'
export GIT_AUTHOR_EMAIL='a'
export GIT_COMMITTER_DATE='2000-01-01T00:00:00+0000'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'
rm -rf server_repo local_repo
mkdir server_repo
cd server_repo
# Create repo.
git init --quiet
git config --local uploadpack.allowfilter 1
git config --local uploadpack.allowanysha1inwant 1
# First commit.
# Directories present in all branches.
mkdir d1 d2
printf 'd1/a' > ./d1/a
printf 'd1/b' > ./d1/b
printf 'd2/a' > ./d2/a
printf 'd2/b' > ./d2/b
# Present only in root.
mkdir 'root'
printf 'root' > ./root/root
git add .
git commit -m 'root' --quiet
# Second commit only on master.
git rm --quiet -r ./root
mkdir 'master'
printf 'master' > ./master/master
git add .
git commit -m 'master commit' --quiet
# Second commit only on mybranch.
git checkout -b mybranch --quiet master~
git rm --quiet -r ./root
mkdir 'mybranch'
printf 'mybranch' > ./mybranch/mybranch
git add .
git commit -m 'mybranch commit' --quiet
echo "# List and identify all objects"
list-objects
echo
# Restore master.
git checkout --quiet master
cd ..
# Clone. Don't checkout for now, only .git/ dir.
git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo
cd local_repo
# List missing objects from master.
echo "# Missing objects after --no-checkout"
git rev-list --all --quiet --objects --missing=print
echo
echo "# Git checkout fails without internet"
mv ../server_repo ../server_repo.off
! git checkout master
echo
echo "# Git checkout fetches the missing file from internet"
mv ../server_repo.off ../server_repo
git checkout master -- d1/a
echo
echo "# Missing objects after checking out d1/a"
git rev-list --all --quiet --objects --missing=print
Đầu ra trong Git v2.19.0:
# List and identify all objects
c6fcdfaf2b1462f809aecdad83a186eeec00f9c1
fc5e97944480982cfc180a6d6634699921ee63ec
7251a83be9a03161acde7b71a8fda9be19f47128
62d67bce3c672fe2b9065f372726a11e57bade7e
b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a
f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b
84de03c312dc741d0f2a66df7b2f168d823e122a d2
0975df9b39e23c15f63db194df7f45c76528bccb d2/a
41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b
7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master
ef29f15c9a7c5417944cc09711b6a9ee51b01d89
19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch
c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e
a0234da53ec608b54813b4271fbf00ba5318b99f root
93ca1422a8da0a9effc465eccbcb17e23015542d root/root
master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec
040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1
040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a d2
040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master
040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch
040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f root
# Missing objects after --no-checkout
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
?308150e8fddde043f3dbbb8573abb6af1df96e63
# Git checkout fails without internet
fatal: '/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
# Git checkout fetches the missing directory from internet
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done.
# Missing objects after checking out d1
?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
?8b25206ff90e9432f6f1a8600f87a7bd695a24af
?41484c13520fcbb6e7243a26fdb1fc9405c08520
?0975df9b39e23c15f63db194df7f45c76528bccb
Kết luận: tất cả các đốm màu ngoại trừ d1/a
bị thiếu. Ví dụ f70a17f51b7b30fec48a32e4f19ac15e261fd1a4
, d1/b
không có ở đó sau khi kiểm trad1/
.
Lưu ý rằng root/root
và mybranch/mybranch
cũng bị thiếu, nhưng --depth 1
ẩn nó khỏi danh sách các tệp bị thiếu. Nếu bạn loại bỏ --depth 1
, sau đó họ hiển thị trên danh sách các tập tin bị thiếu.
Bạn có thể làm điều đó bằng cách
git archive --format=tar --remote=origin HEAD | tar xf -
git archive --format=tar --remote=origin HEAD <file> | tar xf -
Hai biến thể về những gì đã được đưa ra:
git archive --format=tar --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | tar -O -xf -
và:
git archive --format=zip --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | funzip
Chúng ghi tập tin vào đầu ra tiêu chuẩn.
Trong git, bạn không 'kiểm tra' các tập tin trước khi cập nhật chúng - có vẻ như đây là những gì bạn đang theo đuổi.
Nhiều hệ thống như Clearcase, csv, v.v yêu cầu bạn phải 'kiểm tra' một tập tin trước khi bạn có thể thay đổi nó. Git không yêu cầu điều này. Bạn sao chép một kho lưu trữ và sau đó thực hiện các thay đổi trong bản sao lưu trữ cục bộ của bạn.
Khi bạn cập nhật tệp, bạn có thể làm:
git status
Để xem những gì tập tin đã được sửa đổi. Bạn thêm những cái bạn muốn cam kết index
trước tiên ( index
giống như một danh sách cần kiểm tra):
git add .
hoặc là
git add blah.c
Sau đó, git status
sẽ cho bạn thấy tập tin nào đã được sửa đổi và tập tin nào đã index
sẵn sàng để được cam kết hoặc đăng ký.
Để cam kết các tệp vào bản sao của kho lưu trữ của bạn, hãy làm:
git commit -a -m "commit message here"
Xem git
trang web để liên kết đến các hướng dẫn và hướng dẫn.
git format-patch
để tạo một bản vá để gửi ( git format-patch -1
sẽ tạo một bản vá cho chỉ cam kết gần đây nhất của bạn).
Đây là giải pháp hoàn chỉnh để chỉ kéo và đẩy một tệp cụ thể trong kho git:
git clone --no-checkout <git url>
git reset
git checkout origin/master <path to file>
git add <path to file>
git commit -m <message text>
git push
Cũng xem một liên kết cho một số thông tin bổ sung.
Có vẻ như bạn đang cố gắng thực hiện một ý tưởng từ kiểm soát phiên bản tập trung, mà bản chất git không phải là - nó được phân phối. Nếu bạn muốn làm việc với kho git, bạn sao chép nó. Sau đó, bạn có tất cả nội dung của cây công việc và tất cả lịch sử (ít nhất là tất cả mọi thứ dẫn đến đỉnh của nhánh hiện tại), không chỉ là một tệp hoặc ảnh chụp nhanh từ một cam kết duy nhất.
git clone /path/to/repo
git clone git://url/of/repo
git clone http://url/of/repo
Nếu bạn cần một tệp cụ thể từ một nhánh cụ thể từ kho lưu trữ Git từ xa, lệnh là:
git archive --remote=git://git.example.com/project.git refs/heads/mybranch path/to/myfile |tar xf -
Phần còn lại có thể được bắt nguồn từ câu trả lời của @ VonC:
Nếu bạn cần một tệp cụ thể từ nhánh chính thì đó là:
git archive --remote=git://git.example.com/project.git HEAD path/to/myfile |tar xf -
Nếu bạn cần một tệp cụ thể từ một thẻ, đó là:
git archive --remote=git://git.example.com/project.git mytag path/to/myfile |tar xf -
Tôi không thấy những gì làm việc cho tôi được liệt kê ở đây vì vậy tôi sẽ đưa nó vào bất cứ ai trong tình huống của tôi.
Tình hình của tôi, tôi có một kho lưu trữ từ xa có thể 10.000 tệp và tôi cần xây dựng tệp RPM cho hệ thống Linux của mình. Việc xây dựng RPM bao gồm một bản sao git của tất cả mọi thứ. Tất cả tôi cần là một tệp để bắt đầu xây dựng RPM. Tôi có thể sao chép toàn bộ cây nguồn làm những gì tôi cần nhưng phải mất thêm hai phút để tải xuống tất cả các tệp đó khi tất cả những gì tôi cần là một. Tôi đã cố gắng sử dụng tùy chọn lưu trữ git đã thảo luận và tôi đã nhận được Fatal: Hoạt động không được hỗ trợ bởi giao thức. Có vẻ như tôi phải kích hoạt một số tùy chọn lưu trữ trên máy chủ và máy chủ của tôi được duy trì bởi những tên côn đồ quan liêu dường như rất thích làm cho việc hoàn thành công việc trở nên khó khăn.
Điều cuối cùng tôi đã làm là tôi đã vào giao diện web cho bitbucket và xem một tệp tôi cần. Tôi đã nhấp chuột phải vào liên kết để tải xuống một bản sao thô của tập tin và chọn phím tắt sao chép trên mạng sao chép từ cửa sổ bật lên kết quả. Tôi không thể tải xuống tệp thô vì tôi cần tự động hóa mọi thứ và tôi không có giao diện trình duyệt trên máy chủ Linux của mình.
Để thảo luận, điều đó dẫn đến URL:
https://ourArchive.ourCompany.com/projects/ThisProject/repos/data/raw/foo/bar.spec?at=refs%2Fheads%2FTheBranchOfInterest
Tôi không thể tải trực tiếp tệp này từ kho lưu trữ bitbucket vì trước tiên tôi cần đăng nhập. Sau khi đào một chút, tôi thấy điều này đã hoạt động: Trên Linux:
echo "myUser:myPass123"| base64
bXlVc2VyOm15UGFzczEyMwo=
curl -H 'Authorization: Basic bXlVc2VyOm15UGFzczEyMwo=' 'https://ourArchive.ourCompany.com/projects/ThisProject/repos/data/raw/foo/bar.spec?at=refs%2Fheads%2FTheBranchOfInterest' > bar.spec
Sự kết hợp này cho phép tôi tải xuống một tệp tôi cần để xây dựng mọi thứ khác.
Tôi đang thêm câu trả lời này như một cách thay thế để thực hiện kiểm tra chính thức hoặc một số hoạt động địa phương tương tự. Giả sử rằng bạn có quyền truy cập vào giao diện web của nhà cung cấp Git của mình, bạn có thể có thể xem trực tiếp bất kỳ tệp nào tại một cam kết mong muốn nhất định. Ví dụ: trên GitHub, bạn có thể sử dụng một cái gì đó như:
https://github.com/hubotio/hubot/blob/ed25584f/src/adapter.coffee
Dưới đây ed25584f
là 8 ký tự đầu tiên từ hàm băm SHA-1 của cam kết quan tâm, theo sau là đường dẫn đến tệp nguồn.
Similary, trên Bitbucket chúng ta có thể thử:
https://bitbucket.org/cofarrell/stash-browse-code-plugin/src/06befe08
Trong trường hợp này, chúng tôi đặt hàm băm cam kết ở cuối URL nguồn.
Nếu bạn chỉ cần tải xuống tệp, không cần phải kiểm tra với Git.
GitHub Mate dễ dàng hơn nhiều để làm như vậy, đó là tiện ích mở rộng của Chrome, cho phép bạn nhấp vào biểu tượng tệp để tải xuống. cũng là nguồn mở
git
! =github
Nếu bạn đã chỉnh sửa phiên bản cục bộ của tệp và muốn trở lại phiên bản gốc được duy trì trên máy chủ trung tâm, điều này có thể dễ dàng đạt được bằng cách sử dụng Tiện ích mở rộng Git .
Dễ dàng!