Cách nhúng tập lệnh bash trực tiếp vào bên trong bí danh git


82

Tôi có thể nhúng mã bash shell sau đây không:

for name in $(git diff --name-only $1); do git difftool $1 $name & done

trực tiếp vào việc tạo bí danh git:

git config --global alias.diffall ***my-bash-code-here***

Điều này dẫn đến câu hỏi / câu trả lời trước đây của tôi trên SO, nơi tôi đặt mã vào tệp .sh và sau đó đặt bí danh cho tệp:

git config --global alias.diffall '!sh diffall.sh'

Nhưng trong nhiệm vụ không bao giờ kết thúc về sự đơn giản, chắc chắn phải có cách để bỏ qua tệp và chèn mã trực tiếp vào bí danh? Tôi không thể tìm ra định dạng ...

Câu trả lời:


95
git config --global alias.diffall '!sh diffall.sh'

Điều này là thừa theo một cách. Nếu bạn vẫn định thêm 'diffall.sh' vào $ PATH của mình, tại sao không lưu nó dưới dạng 'git-diffall' và tránh khai báo bí danh. Có, "git diffall" sẽ chạy nó.


1
Cái đó. Tuyệt. Ban đầu tôi lo lắng rằng tôi sẽ vô tình chạy một cái gì đó, vì tôi đã viết một vài tập lệnh shell để thực hiện nội dung git và đặt chúng tiền tố 'git-', Nhưng shell (zsh) của tôi không tự động hoàn thành chúng, vì vậy tôi đã phải gõ chúng một cách rõ ràng. Và nếu tôi muốn hành vi tự động hoàn thành, tôi có thể khai báo bí danh git cho lệnh con của chính nó, đây cũng là một yêu cầu mà tôi phải tạo liên kết từ tập lệnh đến lệnh con rõ ràng.
Jon Carter

1
Yup, và đó là một nhị phân bạn chỉ cần tiếng vang lớn:! binary

1
Không phù hợp với tôi, việc sử dụng bên trong một bí danh sẽ !sh git checkout $(git log --branches -1 --pretty=format:'%D' | sed 's/.*, //g')dẫn đến kết quả /usr/lib/git-core/git: /usr/lib/git-core/git: cannot execute binary file. Đã thử nó cả có và không có shngay từ đầu.
Hi-Angel

36

Để chạy các lệnh bên trong bí danh git, và cụ thể là để truyền đối số cho các lệnh đó, bạn có thể sẽ phải tạo một hàm tạm thời mà sau đó bạn gọi ngay lập tức:

$ vim ~/.gitconfig
...
[alias]
    # compare:
    foo = "! echo begin arg=$1/$2/end"
    foo2 = "!f() { echo "begin arg=$1/$2/end"; }; f"

Trong ví dụ này, hàm có thể là những gì bạn cần (và cũng linh hoạt hơn về những gì bạn có thể làm trong một "câu lệnh"); và bạn có thể nói rằng đối với cả hai tùy chọn, các args còn lại của lệnh git chỉ đơn giản được chuyển dưới dạng args cho bí danh, bất kể đó là "echo" hay "f"; việc gọi hàm chỉ đơn giản là sử dụng các args, bỏ qua những gì không được sử dụng rõ ràng:

$ git foo a b c
begin arg=a/b/end a b c

$ git foo2 a b c
begin arg=a/b/end

Một ví dụ khác (liệt kê tất cả các bí danh, dựa trên mẫu phù hợp) (lưu ý: bạn có thể tiếp tục sử dụng lại cùng một tên hàm "f ()" trong suốt .gitconfig):

[alias]
    alias = "!f() { git config --get-regexp "^alias.${1}$" ; }; f"

Đầu tiên trả về bí danh chỉ "foo $", bí danh thứ hai cho "foo. *":

$ git alias foo
alias.foo ! echo begin arg=$1/$2/end

$ git alias 'foo.*'
alias.foo ! echo begin arg=$1/$2/end
alias.foo2 !f() { echo begin arg=$1/$2/end; }; f

(nb: kết quả thực tế có thể khác nhau dựa trên shell; Tôi đang sử dụng cái này với bash trên Linux, Unix & Cygwin (Windows).)


git.wiki.kernel.org/index.php/Aliases#What.27s_new.3F ngầm khuyến nghị sử dụng sh -c, theo cách đó bạn không phải lo lắng về trình bao đăng nhập của người dùng.
clacke

cú pháp hàm mà tôi đã cung cấp có chủ đích di động qua khá nhiều shell (sh / ksh / bash / zsh), và sẽ nhanh hơn khởi chạy một quy trình con. Tôi khuyên bạn vẫn nên sử dụng cú pháp hàm, trừ khi có vấn đề về tính di động cụ thể trên một nền tảng cụ thể.
michael

Nhận xét của bạn đã đưa tôi trở lại câu trả lời này, và có lẽ tôi sẽ sử dụng cách của bạn. Nó tiết kiệm một mức báo giá và những mức đó đủ điên rồ như nó vốn có. :-)
clacke

Đây trông giống như một bài viết đẹp mô tả những gì bạn đang thực hiện: atlassian.com/blog/git/advanced-git-aliases
Gabriel Staples

Lưu ý: Tôi đã đăng một câu hỏi tiếp theo liên quan đến câu trả lời này tại đây: stackoverflow.com/questions/52123145/… . "Làm thế nào để thay thế lệnh git nội bộ, chẳng hạn như git status, với bí danh tùy chỉnh"
Gabriel Staples

24

Tôi không thể tìm thấy trong tài liệu, nhưng nếu bạn tạo một tập lệnh "git- <name>" trong đường dẫn, bạn có thể gọi nó bằng "git name" trong repo của mình.

Xem:

$ cd ~/bin
$ echo "echo I love this log:
>pwd
>git log --graph  --summary --decorate --all" > git-logg
$ chmod +x git-logg
$ cd /path/to/your/repo
$ git logg
I love this log:
/path/to/your/repo
* commit 3c94be44e4119228cc681fc7e11e553c4e77ad04 (whatever-branch)
| Author: myself <my@Laptop.(none)>
| Date:   Fri Apr 1 16:47:20 2011 +0200
| 
|     would have been better not to do it at all
| 
...
$

Vì vậy, bạn có thể viết bất kỳ bí danh nào bạn thích với cách này (khá tối nghĩa).

Thậm chí, bạn có thể thêm tính năng tự động hoàn thành vào lệnh mới xác định một hàm. Thông tin tại đây

$ _git_logg ()
{
  # you can return anything here for the autocompletion for example all the branches
  __gitcomp_nl "$(__git_refs)" 
}

+1, nghĩ rằng nó sẽ chỉ hoạt động từ thư mục git libexec. nhờ để chia sẻ mẹo này
Olivier Refalo

14

Thêm 2 dòng này vào tệp .git / config của bạn sẽ thực hiện thủ thuật.

[alias]
    diffall = '!for name in $(git diff --name-only $1); do git difftool $1 $name & done'

Chỉnh sửa: có lẽ phiên bản git-config cũng hoạt động, nhưng tôi muốn giữ bí danh của mình trong tệp cấu hình để dễ quản lý.

Có một trang hay trên git wiki giải thích bí danh rất rõ ràng: http://git.or.cz/gitwiki/Aliases Đặc biệt, hãy đọc 'bí danh nâng cao có đối số'


git config --global sẽ lưu trữ các bí danh của bạn trên $ HOME / .gitconfig, nơi (IMO) chúng thậm chí còn dễ quản lý hơn; hầu như không có bí danh nào cần phải là kho lưu trữ cụ thể. (Repo cụ thể đi vào repo / .git / config)
u0b34a0f6ae

Cảm ơn David, nhưng nó sẽ không hoạt động với tôi - điều đó hoặc bất kỳ biến thể nào trong liên kết tuyệt vời mà bạn đã đưa vào. Có lẽ tôi nên đề cập rằng tôi đang chạy trong môi trường Windows? Cảm ơn Kaizer, đã đồng ý, đây là 'toàn cầu' đối với tôi.
Seba Illingworth

Ngày nay, git.wiki.kernel.org/index.php/Aliases#Advanced là một nơi tốt để xem xét. (git hoặc liên kết cz đổi hướng đó, nhưng phần này đặc biệt đề cập đến những điều phức tạp chạy với đối số)
clacke

-4

(Từ tài liệu ProGit: http://progit.org/book/ch7-3.html )

Bạn đã thử thêm một tập lệnh trong .git / hooks chưa?

Ví dụ: nếu bạn tạo tập lệnh .git / hooks / post-checkout:

#!/bin/bash

echo "This is run after a 'git checkout'"

và sau đó chạy lệnh:

$ git checkout master
Switched to branch 'master'
This is run after a 'git checkout'

3
hooks phải làm gì với cấu hình, phần mở rộng và bí danh?
Steve Buzonas,
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.