Git có thể bỏ qua một dòng cụ thể không?


114

Tôi đang sử dụng git để đồng bộ hóa với phonegap trong khi thử nghiệm trên trình duyệt gốc của điện thoại. Như vậy, tôi có dòng sau:

var isPhoneGap = false;

Rõ ràng là tôi thay đổi điều này khi xây dựng, nhưng có cách nào tôi có thể thiết lập git để bỏ qua một dòng này không hoặc tôi phải đi và đặt nó vào tệp của chính nó và bỏ qua nó theo cách đó?

Tôi đang sử dụng Gitx và thiết bị đầu cuối trên OSX 10.6.


@ user494461: Bộ lọc Git là cách để làm điều đó: stackoverflow.com/a/16244970/520162
eckes

1
Bạn có thể không phát hiện ra môi trường và sử dụng tệp cấu hình eniroment không?
exussum

Tóm lại: Không. Nhưng tôi đã viết một tập lệnh tiền xử lý để tìm kiếm một số mã nhận xét nhất định và xóa nó trước khi xuất bản lên git. Hãy xem nó tại đây: github.com/franklinchou/ahk_config/blob/master/preprocess.sh
Franklin

Câu trả lời:


103

Nếu tệp của bạn thuộc loại cụ thể, bạn có thể khai báo trình điều khiển bộ lọc nội dung mà bạn có thể khai báo trong .gitattributestệp (như được trình bày trong phần "Mở rộng từ khóa" của " Thuộc tính Git "):

http://git-scm.com/figures/18333fig0702-tn.png

*.yourType filter=yourFilterName

(bạn thậm chí có thể đặt bộ lọc đó cho một tệp cụ thể , nếu bạn muốn)

Triển khai thực hiện:

  • yourFilterName.smudge(được kích hoạt vào git checkout) và

    git config --global filter.yourFilterName.smudge 'sed "s/isPhoneGap = .*/isPhoneGap = true/"'
    
  • yourFilterName.clean(được kích hoạt vào git add)

    git config --global filter.yourFilterName.clean 'sed "s/isPhoneGap = .*/isPhoneGap = false/"'
    

Tệp của bạn sẽ xuất hiện không thay đổi vào ngày git status, nhưng phiên bản đã kiểm tra của nó sẽ có giá trị phù hợp isPhoneGap.


1
Cảm ơn vì điều đó. làm cho nó hoạt động. Bạn có biết cách tạo git diff or trạng thái git`, bỏ qua các bộ lọc không? Vì vậy, tôi vẫn có thể thấy những gì là khác nhau? Trường hợp sử dụng của tôi là để gỡ lỗi nhật ký ... mà cuối cùng tôi muốn xóa ... @jthill @VonC
timh

1
@timh nếu bộ lọc đang hoạt động, trạng thái git hoặc git khác biệt sẽ không hiển thị bất kỳ điều gì.
VonC

1
thật tiếc là không có cách nào đơn giản hơn trong GIT. git ignore <filename> <linenumber> sẽ rất tiện dụng!
kiedysktos 14/09/16

22
@kiedysktos linenumber? Điều gì sẽ xảy ra nếu số dòng thay đổi?
VonC

Điều này rất hiệu quả, nhưng người dùng Windows hãy cẩn thận, gitconfig rất kén ký tự mà nó muốn giữ, vì vậy khi thử một số biểu thức chính quy bán kỳ lạ, bạn có thể gặp rắc rối. Tôi đã kết thúc việc đưa các cuộc gọi sed của mình vào một tệp helper.sh riêng biệt mà tôi đã gọi từ gitconfig của mình với sh ".git/helper.sh"việc đảm bảo chuyển qua bất kỳ tham số nào cho sed với "$@"(tôi cho rằng chỉ đường dẫn tệp được chuyển).
ohaal

43

Bạn có thể dùng

git update-index --assume-unchanged [file]

để bỏ qua những thay đổi của một tệp mà bạn không muốn theo dõi. Tôi sử dụng giải pháp này khi tôi cần có tệp trong kho lưu trữ nhưng tệp này có một số phần thay đổi mà tôi không cần theo dõi luôn.

Khi tệp có những thay đổi quan trọng, bạn phải thực hiện điều này:

git update-index --no-assume-unchanged [file]

Ngoài ra, hãy xem Git doc update-index để biết --[no-]assume-unchangedtham số.

Khi các cờ này được chỉ định, tên đối tượng được ghi cho các đường dẫn sẽ không được cập nhật. Thay vào đó, các tùy chọn này đặt và bỏ đặt bit "giả sử không thay đổi" cho các đường dẫn. Khi bit "giả định không thay đổi" được bật, git ngừng kiểm tra tệp cây làm việc để biết các sửa đổi có thể xảy ra, vì vậy bạn cần hủy đặt bit theo cách thủ công để thông báo cho git khi bạn thay đổi tệp cây làm việc.


2
Làm điều này có tiếp tục tìm nạp phiên bản mới khi tôi thực hiện git pull không?
Saad Rehman Shah

1
@Caffeine khi bạn thực hiện git pull, bạn sẽ nhận được phiên bản cuối cùng đã được cam kết, đây sẽ là phiên bản cuối cùng trước khi bạn thay đổi thành tệp '--assume-changes'.
Carlos

1
Tôi tin rằng đó --skip-worktreelà một lựa chọn tốt hơn cho hầu hết các mục đích. stackoverflow.com/a/39583010/4233593
Jeff Puckett


3
này bỏ qua bản cập nhật cho toàn bộ tập tin không phải là một dòng cụ thể
nikoss

6

Gitx nên cho phép bạn cam kết hoặc bỏ qua các dòng riêng lẻ (bạn có thể biết điều đó rồi), nhưng bạn phải làm điều đó mỗi khi bạn cam kết. Tôi nghĩ sẽ tốt hơn nếu có một tệp cấu hình cho mỗi mục tiêu triển khai (bạn có thể tạo phiên bản cho chúng) và một số tham số thời gian chạy cho tuy nhiên bạn đang khởi động máy chủ (như ./myserver --config=whatever.js).


5

Tiếp tục https://stackoverflow.com/a/20574486/4935114 , @Mike đề xuất tạo một pre-commithook sẽ grepnằm trong các tệp theo giai đoạn cho các dòng mà người ta có thể muốn bỏ qua. Cái móc sẽ kiểm tra xem những dòng đó có được dàn dựng hay không. Nếu vậy, nó là một echocảnh báo và nó exitcó mã 1nên quá trình cam kết sẽ không tiếp tục.

Lấy cảm hứng từ câu trả lời của @ Mike , tôi thấy mình có lẽ đang sử dụng một phiên bản cải tiến của câu móc của anh ấy, tự động đặt reset (có -pcờ) dòng cụ thể mà chúng tôi muốn bỏ qua.

Tôi không chắc hook này sẽ hoạt động trong trường hợp bạn có nhiều tệp với dòng này bị bỏ qua, nhưng pre-commithook này tìm kiếm sự thay đổi trong dòng này trong một tệp cụ thể buildVars.java. Tập lệnh hook trông như thế này khi tôi thử nghiệm nó trên máy tính của mình.

#!/bin/sh

# this hook looks for lines with the text `var isPhoneGap = false;` in the file `buildVars.java` and it resets these lines to the previous state before staged with `reset -p`

if [[ $(git diff --no-ext-diff --cached buildVars.java | grep --count -e "var\ isPhoneGap[\ ]*=[\ ]*") -ne 0 ]]; then
    cat <<EOW
WARNING: You are attempting to commit changes which are not supposed to be commited according to this \`pre-commit\` hook
This \`pre-commit\` hook will reset all the files containing this line to it's previous state in the last commit.
EOW
    echo /$'\n'isPhoneGap$'\n'y$'\n'q | git reset -p
    # BONUS: Check if after reseting, there is no actual changes to be commited and if so, exit 1 so the commit process will abort.
    if [[ $(git diff --no-ext-diff --cached | wc -l) -eq 0 ]]; then
        echo there are no actual changes to be commited and besides the change to the variable \'isPhoneGap\' so I won\'t commit.
        exit 1
    fi
fi

Giải trình

Những gì tôi đã làm là lặp lại một chuỗi điều khiển tìm kiếm regex isPhoneGaptrong một resetquá trình tương tác . Do đó, giả lập người dùng nhấn /để tìm kiếm isPhoneGap, nhấn ykhi được hỏi liệu anh ta có muốn hủy bản vá này hay không và cuối cùng nhấn qđể thoát khỏi tương tác reset.

Quá trình vá ngược tương tác được ghi lại tại đây: https://git-scm.com/docs/git-add#git-add-patch


LƯU Ý: Tập lệnh trên giả định rằng biến interactive.singleKeyfalse. Nếu bạn đã định cấu hình của mình thành true, hãy xóa bất kỳ lệnh nào $'\n'khỏi echolệnh ngay sau cảnh báo.


3

Đây là cách bạn có thể làm điều đó với bộ lọc git :

  1. Tạo / Mở tệp gitattributes:
    • <project root> /. gitattributes (sẽ được cam kết trong repo)
      HOẶC
    • <dự án gốc> /. git / info / thuộc tính (sẽ không được cam kết trong repo)
  2. Thêm một dòng xác định các tệp sẽ được lọc:
    • *.rb filter=gitignore, tức là chạy bộ lọc có tên gitignoretrên tất cả *.rbcác tệp
  3. Xác định gitignorebộ lọc trong gitconfig:
    • $ git config --global filter.gitignore.clean "sed '/#gitignore$/'d", tức là xóa những dòng này
    • $ git config --global filter.gitignore.smudge cat, tức là không làm gì khi kéo tệp từ repo

Lưu ý:
Tất nhiên, điều này dành cho các tệp ruby, được áp dụng khi một dòng kết thúc bằng #gitignore, được áp dụng trên toàn cầu ~/.gitconfig. Sửa đổi điều này theo cách bạn cần cho mục đích của mình.

Cảnh báo!!
Điều này khiến tệp làm việc của bạn khác với repo (tất nhiên). Bất kỳ kiểm tra hoặc giảm giá sẽ có nghĩa là những dòng này sẽ bị mất! Thủ thuật này có vẻ vô dụng vì những dòng này liên tục bị mất khi kiểm tra, rebase hoặc pull, nhưng tôi đã có một trường hợp sử dụng cụ thể để tận dụng nó.

Ngay git stash save "proj1-debug" trong khi bộ lọc không hoạt động (chỉ cần tạm thời vô hiệu hóa nó trong gitconfighoặc một cái gì đó). Bằng cách này, mã gỡ lỗi của tôi luôn có thể được git stash applychuyển thành mã của tôi bất kỳ lúc nào mà không sợ những dòng này vô tình bị phạm phải.

Tôi có một ý tưởng khả thi để giải quyết những vấn đề này, nhưng tôi sẽ thử thực hiện nó vào lúc khác.

Cảm ơn Rudi và jw013 đã đề cập đến bộ lọc git và gitattributes.


2

Trình điều khiển bộ lọc nội dung không phải là một giải pháp tốt. Bạn có thể ẩn dòng này khỏi git status/ etc nhưng nó không thực sự bị bỏ qua. Ngay sau khi bạn thay đổi giá trị, thư mục làm việc của bạn sẽ bị đánh dấu là bẩn mặc dù thay đổi có thể không hiển thị.

Nếu bạn thực sự muốn dòng này nằm ngoài quyền kiểm soát phiên bản, thì việc thay đổi nó thành đối số dòng lệnh hoặc đặt nó trong tệp xây dựng hoặc bao gồm bị bỏ qua có thể là phương tiện thực tế duy nhất.


"Ngay sau khi bạn thay đổi giá trị, thư mục làm việc của bạn sẽ bị đánh dấu là bẩn mặc dù thay đổi có thể không hiển thị": điều này không nên xảy ra, nếu tập lệnh sạch vẫn khôi phục tệp ở nội dung ban đầu của nó.
VonC

Đó là những gì tôi đã nghĩ. Tôi đang sử dụng GitExtensions và nó sẽ hiển thị tệp như đã được sửa đổi ngay cả khi ngăn khác biệt trống. Có thể vì bộ lọc sạch không chạy cho đến khi đăng ký tệp. Có thể vì đó là msysgit, không phải git-git. IDK, YMMV
Patricktokeeffe

1

Tôi đoán đây có thể là điều gì đó xuất hiện trong nhiều dòng nguồn của bạn.

Tôi nghĩ sẽ là sạch nhất nếu có một tệp .userbuildconfig nào đó mà bạn chỉ đưa vào và kiểm tra các giá trị mặc định. Sau đó, bạn có thể sử dụng đề xuất của Carlos để đánh dấu tệp đó một mình là giả sử không thay đổi. Bằng cách này, các thay đổi khác đối với tệp mà bạn cần kiểm tra cài đặt không bị bỏ lỡ.

Điều này có thể cho phép bạn điều chỉnh các macro tiền xử lý cục bộ (Hoặc đối với java như thế này https://stackoverflow.com/a/1813873/1270965 ).


-1

Không. Bạn chỉ có thể bỏ qua các tệp riêng lẻ (và hơn thế nữa) vì các dòng trong .gitignore khớp với tên tệp chứ không phải nội dung tệp. Bạn đã đề cập đến giải pháp cho vấn đề này, tức là bỏ qua một tệp duy nhất có chứa nội dung mà bạn muốn bỏ qua.


Tôi đồng ý, trong trường hợp của tôi, chỉ cần đưa nội dung đó vào một tệp bị bỏ qua là đủ và có thể. Vì vậy, di chuyển tất cả các cài đặt có thể bỏ qua. ở đó. Ngoài ra, tôi đã tạo một bản sao của tệp bị bỏ qua đó và thêm nó vào chỉ mục làm tài liệu tham khảo, vì vậy thông tin về những gì có trong tệp đó sẽ không bị mất.
Urs
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.