Git Alias ​​- คำสั่งและพารามิเตอร์หลายตัว


182

ฉันพยายามสร้างนามแฝงที่ใช้ทั้งคำสั่ง Git และพารามิเตอร์ตำแหน่งต่างๆ มีหน้า Stackoverflow สำหรับแต่ละหน้าและจะปรากฏชัดเจนอย่างเจ็บปวดเมื่อต้องทำทั้งสองอย่าง แต่ฉันมีปัญหา

ตัวอย่างเช่นฉันต้องการสลับไปที่สาขา foo และดำเนินการสถานะ ดังนั้นในของ.gitconfigฉันฉันมี:

  [alias] 
     chs = !sh -c 'git checkout $0 && git status'

ซึ่งไม่ทำงาน ในขณะที่บางสิ่งเช่นนี้จะทำงาน

chs = !sh -c 'git checkout $0'

echoes = !sh -c 'echo hi && echo bye'

ความเข้าใจใด ๆ ที่จะได้รับการชื่นชม


นามแฝงของฉัน: git config --global alias.go '! git commit - a && git pull --rebase && git push && สถานะ git' หมายเหตุ: ใช้เครื่องหมายคำพูดธรรมดา
Marcus Becker

คำตอบ:


157

สิ่งนี้จะใช้งานได้ (ทดสอบด้วย zsh และ bash):

[alias] chs = !git checkout $1 && git status

1
ไม่มันจะไม่ Git จะเปลี่ยนgit chs fooเป็นgit checkout && git status foo
Lily Ballard

24
ที่น่าสนใจจริง ๆ แล้วคอมไพล์เติมตัวแปรตำแหน่งในขณะนี้ในนามแฝงเชลล์ แต่มันก็ยังขาดอยู่เพราะมันยังใช้เป็นข้อโต้แย้งได้ นามแฝงของecho $1 && echo doneเมื่อเรียกด้วยอาร์กิวเมนต์ 'foo' จะส่งออกทั้ง "foo" และ "done foo"
Lily Ballard

7
เครื่องหมายอัศเจรีย์ก่อนหน้านี้สำหรับการเรียกใช้ครั้งแรกgitคืออะไร
Elijah Lynn

21
@ElijahLynn: ในนามแฝงคอมไพล์!หมายถึงค่าชั้นนำส่งผ่านสิ่งทั้งหมดไปยังเชลล์ มิฉะนั้นจะถือว่าคุณพยายามเรียกใช้คำสั่ง git อื่นและส่งผ่านเป็นอาร์กิวเมนต์ไปยังgitไบนารี
ลิลลี่บัลลาร์ด

2
@ Brondahl Clever ผมอยากแนะนำให้;:แทน&& :แม้ว่า และนั่นก็ใช้ได้ดีบนยูนิกซ์เช่นกัน
Lily Ballard

82

สิ่งนี้มีเป้าหมายแบตช์ / msysgit ของ Windows อาจไม่ทำงานในสภาพแวดล้อมอื่น ๆ

ดังที่ Olivier Verdier และ Lily Ballard ได้กล่าวไว้

[alias] chs = !git checkout $1 && git status

เกือบจะได้ผล แต่ให้การทะเลาะโต้เถียงแบบพิเศษเพิ่มเติม ...

git chs demo -> git checkout demo && git status demo

แต่ถ้าคุณเพิ่ม&& :ในส่วนท้ายของนามแฝงของคุณแล้วอาร์กิวเมนต์ปลอมจะถูกใช้เป็นแท็กตำแหน่ง

ดังนั้น

[alias] chs = !git checkout $1 && git status && :

ให้เอาต์พุตที่ถูกต้อง ... git chs demo -> git checkout demo && git status


9
&& :เป็นสีทองและทำให้การทำงานการแก้ปัญหานี้สำหรับคำสั่งที่อาร์กิวเมนต์พิเศษจะมีปัญหา
ดิน

3
@Clay (หรือคนอื่น ๆ ) - มีคนอธิบายให้ BASH-challenged ว่าทำอะไรได้&& :บ้าง?
จัสตินมอร์แกน

7
@JustinMorgan && หมายถึงหากคำสั่งก่อนหน้าเปลี่ยนเป็น 0 (สำเร็จ) ให้รันคำสั่งหลัง && ':', โคลอน, เป็นคำสั่ง shell builtin, ซึ่งไม่ทำอะไรเลยนอกเหนือจากการขยายข้อโต้แย้งและทำการเปลี่ยนเส้นทางและคืนสถานะ 0 นี่คือการใช้งานบางอย่าง: 1. a=123;$aข้อผิดพลาด, แต่a=123; : $aไม่ 2. : > hello.txtล้าง hello.txt 3. if [ "$a" = "hello" ];then : ;fiทำงานได้ดี แต่มีข้อผิดพลาดโดยไม่มี ':' มันเหมือนpassงูหลาม 4. : this is a commentเครื่องหมายโคลอนตามด้วยช่องว่างทำงาน#ในบรรทัดความคิดเห็น
ElpieKay

2
นี่เป็นแฮ็ค ... git ควรยอมรับโหมดคำสั่งหลายโหมด
kchoi

1
ขอบคุณ @ElpieKay สำหรับคำอธิบาย นามแฝงคอมไพล์ในท้องถิ่นของฉันสำหรับหนึ่ง proejct เป็นco = !git checkout public/compiled && git checkout $1และเมื่อฉันทำฉันได้รับข้อความgit co master error: pathspec 'master' did not match any file(s) known to git.ฉันไม่คิดว่าคำตอบนี้จะมีประโยชน์สำหรับฉันเพราะสิ่งแรกที่กล่าวถึงคือ Windows และฉันใช้ Linux แต่คุณอธิบายว่าทำไม
Tyler Collier

73

คุณสามารถกำหนดฟังก์ชั่นเปลือก

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

ฉันเห็นสิ่งนี้ในหน้าสแต็คโอเวอร์โฟลว์อื่น แต่เทอร์มินัล cygwin ของฉันบอกว่าฟังก์ชั่นไม่เป็นที่รู้จักเมื่อฉันพยายามเรียกใช้
สเตลล่า

@Stella: ฉันทิ้งใบเสนอราคาปิดในที่นั่นไม่เป็นประโยชน์ไวยากรณ์ไฟล์ config นี้ ตรวจสอบให้แน่ใจว่าคุณไม่มี
Lily Ballard

2
ว้าว ... น่าเสียดายนี่เป็นปัญหาของรุ่นทั้งหมด ฉันใช้ Git 1.7.3 และไม่สามารถใช้วิธีการเหล่านี้ได้ ฉันอัปเดตเป็น 1.7.6 และ voila ทุกอย่างทำงานได้ ขอบคุณเพื่อน!
สเตลล่า

5
ถ้าใช้ Windows ฉันคิดว่าคุณต้องล้อมนิยามฟังก์ชันเชลล์ด้วยเครื่องหมายคำพูดคู่"
drzaus

4
คำตอบของ Olivier ใช้ไม่ได้กับฉันโดยใช้พารามิเตอร์ (OSX) มันทำงานได้อย่างสมบูรณ์แบบ
Ohad Schneider

25

ฉันสามารถสร้างชื่อแทนคอมไพล์แบบหลายบรรทัดและค่อนข้างซับซ้อนได้ พวกเขาทำงานได้ดีบน Windows แต่ฉันคิดว่าพวกเขาจะทำงานที่อื่นเช่นกัน:

safereset = "!f() { \
                trap 'echo ERROR: Operation failed; return' ERR; \
                echo Making sure there are no changes...; \
                last_status=$(git status --porcelain);\
                if [[ $last_status != \"\" ]]; then\
                    echo There are dirty files:;\
                    echo \"$last_status\";\
                    echo;\
                    echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                    read dirty_operation;\
                    if [ \"$dirty_operation\" == \"Y\" ]; then \
                        echo Resetting...;\
                        git reset --hard;\
                    elif [ \"$dirty_operation\" == \"W\" ]; then\
                        echo Comitting WIP...;\
                        git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                    else\
                        echo Operation cancelled;\
                        exit 1;\
                    fi;\
                fi;\
            }; \
            f"

ผมเขียนโพสต์และมีตัวอย่างอีกไม่กี่ที่นี่


2
สิ่งหนึ่งที่ต้องคำนึงถึงในเรื่องนี้คือการเพิ่ม!f() { : resetเพื่อรับความสำเร็จจากคำสั่งรีเซ็ตgithub.com/git/git/blob/master/contrib/completion/ …
ผู้ใช้

เยี่ยมมาก! บทความนั้นเผยแพร่ภายใต้ลิขสิทธิ์แบบใด คุณจะรังเกียจไหมถ้าฉันแปลส่วนของมันเป็น StackOverflow ในภาษารัสเซีย?
นิค Volynkin

@NickVolynkin ขออภัยเกี่ยวกับการตอบกลับล่าช้า ขอขอบคุณและแน่นอนไปข้างหน้า :)
VitalyB

22
[alias]
chs = !git branch && git status

8
มีไว้!เพื่ออะไร
AutonomousApps

1
ฉันไม่พบ doc สำหรับ!แต่เท่าที่ฉันเห็น git โดยค่าเริ่มต้นจะถือว่า alias เป็นคำสั่ง git ดังนั้นt = statusจะทำงาน อย่างไรก็ตามหากคุณลองt = git statusใช้งานจะไม่ทำงาน (จะบอกว่าไม่พบคำสั่ง "git") ดังนั้นที่ที่!มามันบอกให้เรียกใช้คำสั่งราวกับว่ามันเป็นเปลือกและโดยปกติคุณต้องการเมื่อคุณมีคำสั่ง git หลายต่อนามแฝงเพื่อให้คุณสามารถมีt = !git status && git logตัวอย่างและมันจะทำงาน
เรน

นี่เป็นคำถามที่ StackOverflow ว่าข้อเสนอที่มีเครื่องหมายอัศเจรีย์ในนามแฝง Git (!): stackoverflow.com/questions/21083933/...
Jacob Lockard


6

เป็นไปได้ที่จะมีนามแฝงคอมไพล์หลายเส้นโดยต่อ\ท้ายแต่ละบรรทัด

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "

2
ขอบคุณ! ที่จริงฉันไม่มีปัญหาในการใช้"!git fetch --prune --all; git pull --rebase upstream master; git push origin master"นามแฝง
Droogans

3

ปัญหาที่นี่คือพารามิเตอร์ตำแหน่งดูเหมือนจะถูกส่งไปยังคำสั่งเชลล์สองครั้ง (ณ git 1.9.2) หากต้องการดูสิ่งที่ฉันหมายถึงลองสิ่งนี้:

[alias]
  test = !git echo $*

git test this is my testing stringจากนั้นทำ คุณควรสังเกตผลลัพธ์ต่อไปนี้ (สองบรรทัดสุดท้ายแก้ไขที่นี่เพื่อความชัดเจน):

03:41:24 (release) ~/Projects/iOS$ git test this is my testing string
this is my testing string this is my testing string
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
          #1                         #2

วิธีหนึ่งในการแก้ไขปัญหานี้ก็คือ

[alias]
  chs = !git checkout $1 && git status && git echo x >/dev/null

สิ่งนี้จะใช้พารามิเตอร์ตำแหน่งพิเศษเมื่อได้รับการนำไปใช้กับคำสั่ง echo สุดท้ายและไม่มีผลต่อผลลัพธ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.