Sử dụng git, làm cách nào để bỏ qua một tệp trong một nhánh nhưng nó đã được cam kết ở một nhánh khác?


156

Tôi đã có một dự án mà tôi đang triển khai cho Heroku . Cây mã nguồn bao gồm một loạt các tệp mp3 (trang web sẽ dành cho một dự án ghi âm mà tôi đã tham gia rất nhiều).

Tôi muốn đưa mã nguồn cho nó lên GitHub , nhưng GitHub có giới hạn 300 MB trên tài khoản miễn phí của họ. Tôi không muốn sử dụng 50 MB giới hạn của mình cho một loạt các tệp mp3. Rõ ràng, tôi có thể thêm chúng vào .gitignoretập tin để tránh chúng khỏi repo của tôi.

Tuy nhiên, tôi triển khai để Heroku sử dụng git push heroku. Các tệp mp3 phải có mặt trong nhánh tôi đẩy tới Heroku để chúng được triển khai.

Lý tưởng nhất là tôi muốn .gitignorecác tệp mp3 trong nhánh chính cục bộ của mình để khi tôi đẩy tệp đó sang GitHub, các tệp mp3 không được bao gồm. Sau đó, tôi sẽ giữ một chi nhánh sản xuất tại địa phương có các bản mp3 được cam kết thay vì bỏ qua. Để triển khai, tôi sẽ hợp nhất chủ vào sản xuất, rồi đẩy chi nhánh sản xuất sang Heroku.

Tôi không thể làm điều này để làm việc đúng.

Đây là một ví dụ về những gì tôi đang cố gắng làm ...

$ git init git-ignore-test
$ cd git-ignore-test
$ echo "*.ignored" >> .gitignore
$ git add .gitignore && git commit -m "Ignore .ignored files"
$ touch Foo.ignored

Tại thời điểm này, Foo.ignored bị bỏ qua trong nhánh chính của tôi, nhưng nó vẫn hiện diện, vì vậy dự án của tôi có thể sử dụng nó.

$ git checkout -b unignored
$ cat /dev/null > .gitignore
$ git add Foo.ignored .gitignore && git commit -m "Unignore .ignored files"

Bây giờ tôi đã có một chi nhánh với các tệp này được cam kết, như tôi muốn. Tuy nhiên, khi tôi quay trở lại chi nhánh chính của mình, Foo.ignored đã biến mất.

Bất cứ ai có bất kỳ đề nghị cho một cách tốt hơn để thiết lập này?

Chỉnh sửa: chỉ để làm rõ, tôi muốn các tệp mp3 có mặt ở cả hai nhánh để khi tôi chạy trang cục bộ (sử dụng một trong hai nhánh) thì trang sẽ hoạt động. Tôi chỉ muốn các tệp bị bỏ qua trong một nhánh vì vậy khi tôi đẩy lên GitHub thì chúng cũng không được đẩy. Thông thường, nhánh với các tập tin bị bỏ qua, các tập tin biến mất.


Tại sao các tập tin MP3 bao giờ cần phải được cam kết vào kho?
Dan Loewenherz

4
Với heroku, cam kết repo của bạn là cách duy nhất để có được các tệp đi kèm với ứng dụng của bạn khi bạn triển khai. Cách khác là sử dụng thứ gì đó như Amazon S3 để phục vụ mp3, nhưng tôi muốn tránh điều đó.
Myron Marston

Có vẻ như bạn đang vấp phải nhiều đô la để tiết kiệm xu ... Đám mây Rackspace rất đơn giản để thiết lập và sẽ tốn rất ít để lưu trữ <1 GB tệp ở đó ...
gahooa

3
Tôi nhận thấy bạn đã đánh dấu một câu trả lời là đúng nhưng từ những gì tôi đã đọc thì có thể không đúng. Bạn đã bao giờ thực sự thử câu trả lời và nó đã làm việc cho bạn?
vòng

2
Off Topic: Bạn đã xem xét sử dụng một máy chủ lưu trữ nguồn mở khác chưa? BitBucket không có giới hạn kích thước đối với kho Git của họ, bất kể họ có ở trong tài khoản miễn phí hay không (mặc dù họ đề cập đến việc giữ kích thước trong lý do). Miễn là repo của bạn không vượt quá tầm kiểm soát, đây có thể là một lựa chọn. LƯU Ý: Tôi không liên kết với BitBucket, chỉ là một khách hàng hài lòng.
NightOwl888

Câu trả lời:


83

Giải pháp này dường như chỉ hoạt động đối với các phiên bản git nhất định, được vá. Xem một câu trả lời mới chỉ vào cách giải quyếtmột câu trả lời khác và các nhận xét tiếp theo để biết gợi ý phiên bản nào có thể hoạt động.

Tôi đã viết một bài đăng trên blog về cách sử dụng hiệu quả excludesfilecho các nhánh khác nhau, như một cho github công khai và một cho triển khai heroku.

Đây là nhanh và bẩn:

$ git branch public_viewing
$ cd .git/
$ touch info/exclude_from_public_viewing
$ echo "path/to/secret/file" > info/exclude_from_public_viewing 

sau đó trong tệp .git / config thêm các dòng sau:

[core]
excludesfile = +info/exclude


[branch "public_viewing"]
excludesfile = +info/exclude_from_public_viewing

Bây giờ tất cả các công cụ bỏ qua toàn cầu đều có trong info/excludetệp và chi nhánh cụ thể nằm tronginfo/exclude_from_public_viewing

Mong rằng sẽ giúp!

http://cogniton-mind.tumblr.com/post/1423976659/howto-gitignore-for-different-branches


1
Xin lỗi vì mất quá nhiều thời gian .. nhưng nếu bạn không xóa các tệp .gitignore thì nó sẽ mặc định là những tệp đầu tiên.
Nhận thức. Tìm

4
Điều này không làm việc cho tôi, ngay cả khi dự án không sử dụng .gitignore. Bạn có phiền khi cung cấp bản ghi các lệnh thiết lập điều này từ đầu ( git init, ...) và phiên bản Git bạn đã sử dụng không?
Davor Cubranic

34
Giải pháp này không hoạt động. Có một số cuộc thảo luận trên blog, và không ai ở đó có thể thực hiện công việc này.
spuder


2
Trong vanilla Git, tôi khá chắc chắn rằng điều này không hoạt động và không bao giờ làm. Những người bạn đã quản lý để sao chép này, bạn có thể chia sẻ phiên bản Git của bạn và thông tin liên quan khác về môi trường của bạn không? Có thể bạn có phiên bản vá từ các nhà bảo trì gói Git phân phối của bạn.
Palec

20

Gợi ý quan trọng : Câu trả lời được chấp nhận bởi Cognition.Mind không hoạt động (nữa, trong vài năm nay, hoặc có lẽ cho các phiên bản vanilla của git); xem ý kiến. Một câu trả lời hợp lệ và cách giải quyết có thể được tìm thấy ở đây:

https://stackoverflow.com/a/29583813/2157640

Một cách giải quyết khác (làm việc cho vấn đề cụ thể của tôi, nhưng yêu cầu các thao tác stash thủ công hoặc thực hiện hook) sẽ là git stash -u -a. Điều này là tẻ nhạt khi sự khác biệt là lớn.

Và cuối cùng, giải pháp mà tôi hiện đang thực hiện là phân tách VM mà chúng tôi giữ môi trường phát triển của chúng tôi và thiết lập info/excludesphù hợp cho chi nhánh, tương ứng xóa các tệp / thư mục vi phạm, không được cam kết.


14

Tôi thực sự khuyên bạn nên xem xét đưa các tệp MP3 đó lên S3. Để chúng là một phần trong cú đẩy Heroku của bạn (và do đó là một phần của sên Heroku của bạn) sẽ làm chậm đáng kể thời gian khởi động dyno của bạn. Vì Heroku sử dụng EC2, nếu các tệp trên S3 và chỉ được ứng dụng của bạn truy cập (nếu người dùng không liên kết trực tiếp với S3), bạn thậm chí sẽ không phải trả bất kỳ khoản phí băng thông nào, chỉ tính phí để lưu trữ 50MB.


13

Giả sử chúng ta muốn bỏ qua buildthư mục từ tất cả các chi nhánh khác ngoại trừ productionchi nhánh. Như chúng tôi muốn đẩy buildthư mục trong sản xuất.

1) Không bao gồm buildtrong .gitignore. Nếu bạn làm điều đó, nó sẽ luôn bị bỏ qua cho tất cả các chi nhánh.

2) Tạo một tập tin exclude_from_public_viewingbên trong ./.git/infothư mục (Thư mục này đã tồn tại)touch ./.git/info/exclude_from_public_viewing

3) Bên trong exclude_from_public_viewingviết một dòng (Như bạn đang cố gắng bỏ qua buildcho tất cả các nhánh). !build

4) Có một tập tin hiện có .git/info/exclude. Chúng ta cần thêm dòng sau vào nó.

 build

Chúng tôi muốn bỏ qua buildthư mục nhưng chưa thêm nó vào .gitignore. Vậy làm thế nào git sẽ biết những gì để bỏ qua? Trả lời là chúng tôi đang thêm nó vào excludetập tin và có điều kiện chuyển tập tin đó đếngit config

5) Bây giờ chúng ta phải điều chỉnh buildthư mục unignore cho productionchi nhánh. để làm điều đó thực hiện sau

6) Có một tệp hiện có tên là ./.git/configchúng ta cần thêm vào sau -

a) excludesfile = +info/excludebên dưới[core]

[core]
     excludesfile = +info/exclude

b) Tạo một phần mới vào cuối ./.git/confignhư

[branch "production"]
    excludesfile = +info/exclude_from_public_viewing

Giải pháp 2

Có một giải pháp thay thế thông minh. Hãy nói rằng bạn muốn thêm build/thư mục trong productionnhánh và bỏ qua nó trong tất cả các nhánh khác.

1) Thêm nó vào gitignoretập tin của bạn .

2) Trong nhánh sản xuất, trong khi thực hiện git add, buộc thêm buildthư mục:git add -f --all build/


Và điều này khác với giải pháp được chấp nhận như thế nào? Với phiên bản git nào bạn đã thử nó? Vì câu trả lời được liên kết nói rằng nó thất bại vì không có hỗ trợ cho branch.<name>.excludesfilegit (nữa?), Chỉ cho core.excludesfilevà các thử nghiệm của riêng tôi dường như đã khẳng định điều này.
Murphy

@murphy nó ​​hoạt động tốt với git version 2.7.4 (Apple Git-66)và tôi chưa sử dụng branch.<name>.excludesfile trong giải pháp của mình.
buổi sáng

4
@sacco: Tôi đã thử điều này theo trường hợp sử dụng của OP và tệp vẫn biến mất khi tôi chuyển từ sản xuất sang chế độ chính. Lưu ý rằng thư mục "xây dựng" phải được cam kết vào nhánh "sản xuất". (Ngoài ra, tôi lưu ý rằng nếu tôi không cam kết thư mục "build" trong nhánh "sản xuất", nhánh "sản xuất" sẽ bỏ qua sự hiện diện của thư mục "build" - tức là [nhánh "sản xuất"] không bao gồm cấu hình 't làm việc). Tôi sử dụng chính xác cùng một phiên bản git như của bạn. Tôi cũng đã thử cách tiếp cận [nhánh "sản xuất"] để bỏ qua tệp chỉ trong nhánh sản xuất, nó cũng không hoạt động, như Murphy nói.
cần

Giải pháp 2 là thứ mà tôi đang tìm kiếm. Cảm ơn!
Vyacheslav Cotruta

4

Bạn đã thử có .gitignore khác trong chi nhánh của bạn chưa?

Bạn sẽ có thể bỏ qua những gì bạn muốn dựa trên nhánh bạn đang ở miễn là các tệp không được theo dõi trên nhánh đó.


6
Tôi đã thử nó. Nếu bạn nhìn vào các lệnh tôi đã đăng ở trên, bạn sẽ thấy đó chính xác là những gì tôi đã làm. Vấn đề là khi tôi chuyển từ nhánh có tệp được kiểm tra sang nhánh có tệp bị bỏ qua, git sẽ loại bỏ tệp. Tôi muốn giữ các mp3 trong nhánh chính của mình để trang web hoạt động chính xác ở chế độ dev, mặc dù các tệp bị bỏ qua.
Myron Marston

1
anh ấy đã nói rằng đó là những gì anh ấy đã làm. có lẽ chỉ cần xóa câu trả lời này có thể là tốt nhất :-) nó gây mất tập trung.
blamb

3

1. Tóm tắt

  1. Tôi sử dụng Travis CI để triển khai ( nó hỗ trợ triển khai Heroku )
  2. Tôi thêm vào .travis.yml:

    before_deploy:
    - mv misc/.gitignore .gitignore
    

    Trong đó misc- bất kỳ thư mục, có chứa khác .gitignore.

    mvTập tin di chuyển lệnh UNIX ; ghi đè, nếu tập tin đã tồn tại.

Khi dự án triển khai Travis CI, Travis CI sẽ không chuyển sang triển khai các tệp và thư mục của nhà cung cấp , mà bỏ qua misc/.gitignore(không phải trong bản gốc .gitignorecủa các nguồn).


2. Hạn chế

  1. Câu trả lời này có thể không phù hợp với mọi điều kiện của tác giả. Nhưng câu trả lời này trả lời câu hỏi Sử dụng git, làm cách nào để bỏ qua một tệp trong một nhánh nhưng nó có được cam kết ở nhánh khác không?
  2. Tôi không phải là người dùng Heroku, ví dụ của tôi cho GitHub , không phải cho Heroku. Dữ liệu của câu trả lời này hoạt động với tôi trong GitHub, nhưng có thể không hoạt động trên Heroku.

3. Sự liên quan

Câu trả lời này có liên quan đến tháng 4 năm 2018. Trong tương lai, dữ liệu của câu trả lời này có thể bị lỗi thời.


4. Trình diễn

dự án thực sự của tôi .

Ví dụ về triển khai thành công .

4.1. Bài tập

Tôi triển khai dự án của mình từ nhánh src đến nhánh nhánh của cùng một kho lưu trữ.

Tôi muốn, tập tin đó PaletteMira.suricate-profile:

  • Máy cục bộ - tồn tại cho tất cả các chi nhánh,
  • nhánh từ xa src - không tồn tại,
  • chi nhánh từ xa - tồn tại.

Nếu tôi hiểu chính xác tác giả của câu hỏi, anh ta có nhiệm vụ tương tự.

4.2. src

chi nhánh nguồn - SashaYAML .

Một phần của .travis.yml:

before_deploy:
- mv misc/.gitignore .gitignore

deploy:
  provider: pages
  on:
    branch: SashaYAML
  keep-history: true
  skip-cleanup: true
  target-branch: SashaDevelop
  repo: Kristinita/PaletteMira
  github-token: $GITHUB_TOKEN
  committer-from-gh: true
  project-name: PaletteMira
verbose: true

Một phần của .gitignore:

*.sublime-snippet
*.suricate-profile

Một phần của misc/.gitignore

*.sublime-snippet

*.suricate-profilekhông trong misc/.gitignore.

PaletteMira.suricate-profile không tồn tại trong chi nhánh này từ xa, nhưng tồn tại cục bộ.

4.3. định mệnh

chi nhánh đích - SashaDevelop

Một phần của .gitignore:

*.sublime-snippet

*.suricate-profilekhông trong misc/.gitignore.

PaletteMira.suricate-profiletồn tại cho chi nhánh này từ xa và địa phương.

4.4. Các bước để tái sản xuất

Tôi bật kho lưu trữ PaletteMira GitHub cho Travis CI → Tôi đặt biến môi trường $GITHUB_TOKEN với giá trị - mã thông báo GitHub của tôi→ Tôi thực hiện bất kỳ cam kết nào với nhánh src của mình.

Nếu không có lỗi, tôi phải có hành vi mong đợi .


0

Bạn có thể cam kết và đẩy từ Heroku?

ví dụ: Thêm âm thanh, đẩy chúng vào github và vào heroku, xóa các tệp trên bản sao đang hoạt động trên Heroku. Loại bỏ âm thanh từ repo nhưng không phải từ đĩa, sau đó đẩy sự thay đổi đó trở lại github.


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.