ลบ git remote tags ทั้งหมดโดยใช้คำสั่ง awk และ xargs
Tags: git, programming
Published: 2021-01-31 01:22:19

เมื่อวานเรารู้วิธี [ลิสต์ และ ลบ git remote tags](https://dev.to/iporsut/git-remote-tag-2n33) กันไปแล้ว วันนี้จะมาดูว่าถ้าเราต้องการลบ remote tags ทั้งหมดนั้นเราสามารถทำได้ยังไงบ้าง

จากเมื่อวานที่เราสั่ง list remote tags เราใช้คำสั่งแบบนี้

```
$ git ls-remote --tags

d6602ec5194c87b0fc87103ca4d67251c76f233a        refs/tags/v0.99
f25a265a342aed6041ab0cc484224d9ca54b6f41        refs/tags/v0.99.1
7ceca275d047c90c0c7d5afb13ab97efdf51bd6e        refs/tags/v0.99.3
c5db5456ae3b0873fc659c19fafdde22313cc441        refs/tags/v0.99.2
0918385dbd9656cab0d1d81ba7453d49bbc16250        refs/tags/junio-gpg-pub
```

จะเห็นว่าข้อมูลนั้นแสดงออกมาเป็น 2 columns ส่วนแรกคือ sha ID ของ tag อีกอีกส่วนคือ refs ของ tags ซึ่งเมื่อวานเราก็เห็นแล้วว่าในการลบนั้นเราใช้ refs ของ tag ในการลบได้เช่นแบบนี้

```
$ git push origin :refs/tags/v1.0

To https://github.com/username/repo.git
 - [deleted]         v1.0
```

ดังนั้นถ้าเราอยากลบทั้งหมดเราก็ต้องเราชื่อ refs ทั้งหมดออกมาแล้ววนซ้ำเพื่อสั่งลบ ทีนี้ใน command line เรามี 2 คำสั่ง (โปรแกรม) ที่ช่วยเราทำสองขั้นตอนนี้ได้คือ awk และ xargs ร่วมกับความสามารถในการ pipe ของ Unix base OS อย่าง macOS หรือ Linux (แม้แต่ Windows ก็มี WSL ให้ใช้ command line แบบนี้ได้)

## กรองเอาแค่ refs ด้วย awk
[awk](https://linux.die.net/man/1/awk) เป็นคำสั่งที่ช่วยเรา transform input text ในแต่ละบรรทัดโดยสามารถกำหนด regular expression เพื่อ matching line input ที่ต้องการ กับ action ที่จะจัดการ transform บรรทัดที่ match ได้

แต่สำหรับโจทย์ที่เราต้องการนั้นไม่ซับซ้อนอะไร ตัว awk นั้นจะแยกข้อความในบรรทัดของเราด้วย white space character ให้อยู่แล้วโดยแต่ละส่วนจะแยกอยู่ในตัวแปรลัษณะแบบนี้ $1, $2, ... โดยเลขคือลำดับของ column เช่น $1 คือ column ที่ 1 , $2 คือ column ที่ 2 อย่างโจทย์ของเรา $1 คือข้อมูล sha ID ส่วน $2 คือ refs ของ tag

จากนั้นเราจะใช้คำสั่ง print เพื่อเลือกที่จะเอาแค่ $2 คือ refs tag ออกมา โดยเราจะเพิ่ม `:` ด้านหน้าด้วย เพราะตอนสั่งลบ จำเป็นต้องมี `:` ด้านหน้า ref สรุปเราสามารถลิสต์แล้วเอาแค่ refs tag ออกมาด้วย awk โดยสั่งแบบนี้

```
$ git ls-remote --tags | awk '{ print ":"$2 }'
:refs/tags/v0.99
:refs/tags/v0.99.1
:refs/tags/v0.99.3
:refs/tags/v0.99.2
:refs/tags/junio-gpg-pub
```

จะเห็นว่าวิธีเขียนคำสั่งของ awk แบบง่ายๆคือใช้ single quote ครอบแล้วก็คำสั่งภายใน `{}` อีกทีนึง

หลังจากเราได้ลิสต์ของ refs แล้วเราจะไปใช้ xargs อีกคำสั่งเพื่อช่วยให้เราลบทุก tags ที่ลิสต์ได้อีกทีนึง

# ลบทุก tags ที่ลิสต์ได้โดยใช้ xargs ช่วย
[xargs](https://linux.die.net/man/1/xargs) เป็นคำสั่งที่จะช่วยให้เรารันคำสั่งที่ต้องการ โดยจะรับค่าจาก standard input ที่ pipe มาเอาไปเป็น option ให้กับคำสั่งที่จะรัน เช่นจะเห็นว่าจากขั้นตอนที่แล้ว เราอยากได้ refs ในแต่ละบรรทัดเพื่อมาเรียก `git push origin :refs/tags/v1.0` เราสามารถสั่ง xargs ให้เรียกได้แบบนี้

```
$ git ls-remote --tags | awk '{ print ":"$2 }' | xargs -n 1 git push origin
```

เราใส่ option `-n 1` เพื่อบอก xargs ว่าให้เอา input แค่ 1 ค่าต่อการเรียกคำสั่ง 1 ครั้งนั่นเอง

ทั้ง awk และ xargs มีประโยชน์มากในการที่เราจะเขียน shell script เพื่อกรองข้อความแล้วทำอะไรซ้ำๆให้กับเรา อ่าน manual ของทั้งสองคำสั่งต่อได้ที่นี่

awk : https://linux.die.net/man/1/awk
xargs : https://linux.die.net/man/1/xargs

## ขอฝาก Buy Me a Coffee
สำหรับท่านใดที่อ่านแล้วชอบโพสต์ต่างๆของผมที่นี่ ต้องการสนับสนุนค่ากาแฟเล็กๆน้อยๆ สามารถสนับสนุนผมได้ผ่านทาง Buy Me a Coffee คลิ๊กที่รูปด้านล่างนี้ได้เลยครับ

<a href="https://www.buymeacoffee.com/weerasak" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>

ส่วนท่านใดไม่สะดวกใช้บัตรเครดิต หรือ Paypal สามารถสนับสนุนผมได้ผ่านทาง PromptPay โดยดู QR Code ได้จากโพสต์ที่พินเอาไว้ได้ที่ Page DevDose ครับ https://web.facebook.com/devdoseth

ขอบคุณครับ 🙏