mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 15:36:21 -04:00
Compare commits
No commits in common. "main" and "6.4.0" have entirely different histories.
|
|
@ -1,30 +0,0 @@
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.patch]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[*.html]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[*.py]
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.bats]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[tests/*.sh]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 4
|
|
||||||
2
.github/.ignore_words
vendored
2
.github/.ignore_words
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
gool
|
|
||||||
Cant
|
|
||||||
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -1,12 +0,0 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
Note
|
|
||||||
|
|
||||||
* Mark the PR as draft until it's ready to be reviewed.
|
|
||||||
* Please update the documentation to reflect the changes made in the PR.
|
|
||||||
* If the command is covered by tests under ./tests, please add/update tests for any changes unless you have a good reason.
|
|
||||||
* Make a new commit to resolve conversations instead of `push -f`.
|
|
||||||
* To resolve merge conflicts, merge from the `main` branch instead of rebasing over `main`.
|
|
||||||
* Please wait for the reviewer to mark a conversation as resolved.
|
|
||||||
|
|
||||||
-->
|
|
||||||
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
102
.github/workflows/ci.yml
vendored
102
.github/workflows/ci.yml
vendored
|
|
@ -1,112 +1,28 @@
|
||||||
name: ci
|
name: ci
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [ master ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [ master ]
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out code.
|
|
||||||
uses: actions/checkout@v7
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: 'Get Changed Files'
|
|
||||||
id: 'files'
|
|
||||||
run: |
|
|
||||||
CHANGED_FILES=$(git diff --name-only "${BASE_SHA:-$BEFORE_SHA}...${HEAD_SHA:-$GITHUB_REF}")
|
|
||||||
echo "::notice::Changed files: $CHANGED_FILES"
|
|
||||||
{
|
|
||||||
echo "added_modified<<EOF"
|
|
||||||
echo "$CHANGED_FILES"
|
|
||||||
echo "EOF"
|
|
||||||
} >> "$GITHUB_OUTPUT"
|
|
||||||
env:
|
|
||||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
||||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
||||||
BEFORE_SHA: "${{ github.event.before }}"
|
|
||||||
- name: 'Check Generated Manuals'
|
|
||||||
run: |
|
|
||||||
failed=0
|
|
||||||
while IFS= read -r source; do
|
|
||||||
case "$source" in
|
|
||||||
man/git-*.md)
|
|
||||||
stem=${source%.md}
|
|
||||||
for generated in "$stem.1" "$stem.html"; do
|
|
||||||
if ! grep -Fqx -- "$generated" <<< "$CHANGED_FILES"; then
|
|
||||||
echo "::error file=$source::$generated must be updated with $source"
|
|
||||||
failed=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done <<< "$CHANGED_FILES"
|
|
||||||
exit "$failed"
|
|
||||||
env:
|
|
||||||
CHANGED_FILES: "${{ steps.files.outputs.added_modified }}"
|
|
||||||
- uses: 'actions/setup-go@v7'
|
|
||||||
with:
|
|
||||||
go-version: '1.20'
|
|
||||||
- name: 'Install EditorConfig Lint'
|
|
||||||
run: go install 'github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@latest'
|
|
||||||
- name: 'Check EditorConfig Lint'
|
|
||||||
run: echo "$FILES" | xargs ~/go/bin/editorconfig-checker
|
|
||||||
env:
|
|
||||||
# NOTE: use env to pass the output in order to avoid possible injection attacks
|
|
||||||
FILES: "${{ steps.files.outputs.added_modified }}"
|
|
||||||
- name: checkstyle
|
|
||||||
run: ./scripts/checkstyle.py
|
|
||||||
- name: Shellcheck
|
|
||||||
run: shellcheck --severity=error bin/* ./*.sh
|
|
||||||
|
|
||||||
typo:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out code.
|
|
||||||
uses: actions/checkout@v7
|
|
||||||
- name: Install codespell
|
|
||||||
run: python3 -m pip install codespell==2.4
|
|
||||||
- name: spell check
|
|
||||||
run: |
|
|
||||||
git grep --cached -l '' . | \
|
|
||||||
grep -v -e 'History\.md' -e 'AUTHORS' -e 'man/.*\.1' -e 'man/.*\.html' | \
|
|
||||||
xargs codespell --ignore-words=.github/.ignore_words
|
|
||||||
|
|
||||||
test-bats:
|
|
||||||
name: 'Test with Bats'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v7
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Setup Bats
|
|
||||||
id: setup-bats
|
|
||||||
uses: bats-core/bats-action@4.0.0
|
|
||||||
with:
|
|
||||||
bats-version: 'v1.8.1'
|
|
||||||
- name: Test with Bats
|
|
||||||
env:
|
|
||||||
BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }}
|
|
||||||
TERM: xterm
|
|
||||||
run: bats ./tests
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- ubuntu-latest
|
- ubuntu-18.04
|
||||||
- macos-latest
|
- macos-latest
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code.
|
- name: Check out code.
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v2
|
||||||
- name: Linux Install
|
- name: Linux Install
|
||||||
if: matrix.platform == 'ubuntu-latest'
|
if: matrix.platform == 'ubuntu-18.04'
|
||||||
run: sudo apt-get install -y bsdmainutils
|
run: |
|
||||||
|
sudo apt-get install -y bsdmainutils
|
||||||
- name: Script
|
- name: Script
|
||||||
run: ./check_integrity.sh
|
run: |
|
||||||
|
./check_integrity.sh $(find bin | cut -b 5- | xargs)
|
||||||
- name: Brew release
|
- name: Brew release
|
||||||
if: matrix.platform == 'macos-latest'
|
if: matrix.platform == 'macos-latest'
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
18
.github/workflows/stale.yaml
vendored
18
.github/workflows/stale.yaml
vendored
|
|
@ -1,18 +0,0 @@
|
||||||
name: "Maintenance: Close Stale PRs"
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "30 1 * * *"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: "write"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
runs-on: "ubuntu-latest"
|
|
||||||
if: github.repository_owner == 'tj'
|
|
||||||
steps:
|
|
||||||
- uses: "actions/stale@v11"
|
|
||||||
with:
|
|
||||||
close-pr-message: "This PR was closed because it has been stalled for 365 days with no activity. Feel free to make a new PR if you wish to continue"
|
|
||||||
days-before-pr-stale: 350
|
|
||||||
days-before-pr-close: 15
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
.venv/
|
|
||||||
__pycache__/
|
|
||||||
coverage/
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "vendor/bats-all"]
|
|
||||||
path = vendor/bats-all
|
|
||||||
url = https://github.com/hyperupcall/bats-all
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
[pytest]
|
|
||||||
minversion = 7.4
|
|
||||||
addopts = -ra -q
|
|
||||||
testpaths = tests
|
|
||||||
faulthandler_timeout = 5
|
|
||||||
62
AUTHORS
62
AUTHORS
|
|
@ -1,23 +1,25 @@
|
||||||
git-extras is written and maintained by various contributors:
|
git-extras is written and maintained by TJ Holowaychuk and
|
||||||
|
various contributors:
|
||||||
|
|
||||||
|
Development Lead
|
||||||
|
````````````````
|
||||||
|
- TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
|
||||||
Maintainers
|
Maintainers
|
||||||
```````````
|
```````````
|
||||||
- TJ Holowaychuk <tj@vision-media.ca>
|
|
||||||
- Hemanth.HM <hemanth.hm@gmail.com>
|
- Hemanth.HM <hemanth.hm@gmail.com>
|
||||||
- Nimit Kalra <me@nimit.io>
|
- Nimit Kalra <me@nimit.io>
|
||||||
- Nicolai Skogheim <nicolai.skogheim@gmail.com>
|
- Nicolai Skogheim <nicolai.skogheim@gmail.com>
|
||||||
- spacewander <spacewanderlzx@gmail.com>
|
- spacewander <spacewanderlzx@gmail.com>
|
||||||
- Edwin Kofler <edwin@kofler.dev>
|
|
||||||
- Leroy <vanpipy@gmail.com>
|
|
||||||
|
|
||||||
Patches and Suggestions
|
Patches and Suggestions
|
||||||
```````````````````````
|
```````````````````````
|
||||||
- Jonhnny Weslley
|
- Jonhnny Weslley
|
||||||
- Tobias Fendin
|
|
||||||
- LeeW
|
- LeeW
|
||||||
- timfeirg
|
|
||||||
- Niklas Schlimm
|
- Niklas Schlimm
|
||||||
|
- Tobias Fendin
|
||||||
- nickl-
|
- nickl-
|
||||||
|
- timfeirg
|
||||||
- CJ
|
- CJ
|
||||||
- Paul Wise
|
- Paul Wise
|
||||||
- Damien Tardy-Panis
|
- Damien Tardy-Panis
|
||||||
|
|
@ -25,7 +27,6 @@ Patches and Suggestions
|
||||||
- Yuriy VG
|
- Yuriy VG
|
||||||
- Leila Muhtasib
|
- Leila Muhtasib
|
||||||
- Richard Fearn
|
- Richard Fearn
|
||||||
- Bill Wood
|
|
||||||
- Jesús Espino
|
- Jesús Espino
|
||||||
- Rémy HUBSCHER
|
- Rémy HUBSCHER
|
||||||
- go2null
|
- go2null
|
||||||
|
|
@ -34,43 +35,37 @@ Patches and Suggestions
|
||||||
- Jan Schulz
|
- Jan Schulz
|
||||||
- Kenneth Reitz
|
- Kenneth Reitz
|
||||||
- Mark Pitman
|
- Mark Pitman
|
||||||
- Peter Benjamin
|
|
||||||
- Günther Grill
|
|
||||||
- Luke Childs
|
- Luke Childs
|
||||||
- Sasha Khamkov
|
- Sasha Khamkov
|
||||||
- equt
|
- equt
|
||||||
- oikarinen
|
|
||||||
- vyas
|
- vyas
|
||||||
- Don Harper
|
- Don Harper
|
||||||
- Pierre Ayoub
|
|
||||||
- Robin Winslow
|
- Robin Winslow
|
||||||
- Ross Smith II
|
|
||||||
- Yi EungJun
|
- Yi EungJun
|
||||||
- grindhold
|
- grindhold
|
||||||
- wyattscarpenter
|
|
||||||
- Aggelos Orfanakos
|
- Aggelos Orfanakos
|
||||||
- Camille Reynders
|
- Camille Reynders
|
||||||
- Carlos Prado
|
- Carlos Prado
|
||||||
- Chris Hall
|
- Chris Hall
|
||||||
- Damian Krzeminski
|
- Damian Krzeminski
|
||||||
- NANRI
|
- NANRI
|
||||||
|
- Peter Benjamin
|
||||||
- Alexander Krasnukhin
|
- Alexander Krasnukhin
|
||||||
- Phally
|
- Phally
|
||||||
- Rico Sta. Cruz
|
- Rico Sta. Cruz
|
||||||
- Takuma Yamaguchi
|
- Takuma Yamaguchi
|
||||||
- thomas menzel
|
- thomas menzel
|
||||||
|
- vanpipy
|
||||||
- vr8ce
|
- vr8ce
|
||||||
- Brian J Brennan
|
- Brian J Brennan
|
||||||
- Dominik Gedon
|
- Dominik Gedon
|
||||||
- Hogan Long
|
- Hogan Long
|
||||||
- Ivan Malopinsky
|
- Ivan Malopinsky
|
||||||
- John Bachir
|
|
||||||
- Jonathan "Duke" Leto
|
- Jonathan "Duke" Leto
|
||||||
- Julio Napurí
|
- Julio Napurí
|
||||||
- Justin Dugger
|
- Justin Dugger
|
||||||
- Nils Winkler
|
- Nils Winkler
|
||||||
- Philipp Klose
|
- Philipp Klose
|
||||||
- Raphael Boidol
|
|
||||||
- Richard Russon
|
- Richard Russon
|
||||||
- Sam Bostock
|
- Sam Bostock
|
||||||
- Vladimir Jimenez
|
- Vladimir Jimenez
|
||||||
|
|
@ -82,11 +77,9 @@ Patches and Suggestions
|
||||||
- Alexis GRIMALDI
|
- Alexis GRIMALDI
|
||||||
- Allan Odgaard
|
- Allan Odgaard
|
||||||
- Andre Cerqueira
|
- Andre Cerqueira
|
||||||
- Austin Ziegler
|
|
||||||
- Beth Skurrie
|
- Beth Skurrie
|
||||||
- Brice Dutheil
|
- Brice Dutheil
|
||||||
- Curtis McEnroe
|
- Curtis McEnroe
|
||||||
- Daniele Paolella
|
|
||||||
- David Rogers
|
- David Rogers
|
||||||
- Devin Withers
|
- Devin Withers
|
||||||
- Domenico Rotiroti
|
- Domenico Rotiroti
|
||||||
|
|
@ -95,9 +88,7 @@ Patches and Suggestions
|
||||||
- Gert Van Gool
|
- Gert Van Gool
|
||||||
- Guillaume Seren
|
- Guillaume Seren
|
||||||
- Hozefa
|
- Hozefa
|
||||||
- Igor Ostapenko
|
|
||||||
- Jean Jordaan
|
- Jean Jordaan
|
||||||
- Joshua Li
|
|
||||||
- Justin Guenther
|
- Justin Guenther
|
||||||
- Kylie McClain
|
- Kylie McClain
|
||||||
- Marc Harter
|
- Marc Harter
|
||||||
|
|
@ -131,7 +122,6 @@ Patches and Suggestions
|
||||||
- Andrew Griffiths
|
- Andrew Griffiths
|
||||||
- Andrew Marcinkevičius
|
- Andrew Marcinkevičius
|
||||||
- Andrew Starr-Bochicchio
|
- Andrew Starr-Bochicchio
|
||||||
- Andrew Sullivan Cant
|
|
||||||
- Andrey Elizarov
|
- Andrey Elizarov
|
||||||
- Angel Aguilera
|
- Angel Aguilera
|
||||||
- Antoine Beaupré
|
- Antoine Beaupré
|
||||||
|
|
@ -149,9 +139,7 @@ Patches and Suggestions
|
||||||
- Christophe Badoit
|
- Christophe Badoit
|
||||||
- Ciro Nunes
|
- Ciro Nunes
|
||||||
- CleanMachine1
|
- CleanMachine1
|
||||||
- CodeByZach
|
|
||||||
- Craig MacGregor
|
- Craig MacGregor
|
||||||
- Dan Goodliffe
|
|
||||||
- Dan Jackson
|
- Dan Jackson
|
||||||
- Dan Kilman
|
- Dan Kilman
|
||||||
- Daniel Bruder
|
- Daniel Bruder
|
||||||
|
|
@ -164,44 +152,35 @@ Patches and Suggestions
|
||||||
- Edward Betts
|
- Edward Betts
|
||||||
- Eli Schwartz
|
- Eli Schwartz
|
||||||
- Emil Kjelsrud
|
- Emil Kjelsrud
|
||||||
- Erik Skultety
|
|
||||||
- François M
|
- François M
|
||||||
- George Crabtree
|
- George Crabtree
|
||||||
- Gerrit-K
|
|
||||||
- Greg Allen
|
- Greg Allen
|
||||||
- Guilhem Saurel
|
|
||||||
- Guillermo Rauch
|
- Guillermo Rauch
|
||||||
- Gunnlaugur Thor Briem
|
- Gunnlaugur Thor Briem
|
||||||
- Hasse Ramlev Hansen
|
- Hasse Ramlev Hansen
|
||||||
- Heiko Becker
|
- Heiko Becker
|
||||||
- Hugo Ruiz-Mireles
|
|
||||||
- Isaac Mungai
|
- Isaac Mungai
|
||||||
- J.C. Yamokoski
|
- J.C. Yamokoski
|
||||||
- Jack O. Wasey
|
- Jack O. Wasey
|
||||||
- James Manning
|
- James Manning
|
||||||
- James Zhu
|
- James Zhu
|
||||||
- Jan Krueger
|
- Jan Krueger
|
||||||
- Jared Baur
|
|
||||||
- Jarod Stewart
|
- Jarod Stewart
|
||||||
- Jason Young
|
- Jason Young
|
||||||
- Jens K. Mueller
|
- Jens K. Mueller
|
||||||
- Jeremy Lin
|
- Jeremy Lin
|
||||||
- Jesse Sipprell
|
- Jesse Sipprell
|
||||||
- Jianjin Fan
|
- Jianjin Fan
|
||||||
- Jobin Kurian
|
|
||||||
- Johannes Ewald
|
- Johannes Ewald
|
||||||
- John Evans
|
- John Evans
|
||||||
- John Hoffmann
|
- John Hoffmann
|
||||||
- Jon Ander Peñalba
|
- Jon Ander Peñalba
|
||||||
- Josh McKinney
|
|
||||||
- Joshua Appelman
|
- Joshua Appelman
|
||||||
- José María Gutiérrez @TheTechOddBug
|
- José María Gutiérrez @TheTechOddBug
|
||||||
- Katrin Leinweber
|
- Katrin Leinweber
|
||||||
- Kevin Woo
|
- Kevin Woo
|
||||||
- Konstantin Schukraft
|
- Konstantin Schukraft
|
||||||
- Kurban Mallachiev
|
|
||||||
- Leandro López
|
- Leandro López
|
||||||
- Lone
|
|
||||||
- Luis Miguel Hernanz
|
- Luis Miguel Hernanz
|
||||||
- Maarten Winter
|
- Maarten Winter
|
||||||
- Marco Glasbergen
|
- Marco Glasbergen
|
||||||
|
|
@ -209,15 +188,12 @@ Patches and Suggestions
|
||||||
- Mathieu D. (MatToufoutu)
|
- Mathieu D. (MatToufoutu)
|
||||||
- Matt
|
- Matt
|
||||||
- Matt Colyer
|
- Matt Colyer
|
||||||
- Matt Headley
|
|
||||||
- Matthew Avant
|
- Matthew Avant
|
||||||
- Mattias Andersson
|
|
||||||
- Michael Komitee
|
- Michael Komitee
|
||||||
- Michael Matuzak
|
- Michael Matuzak
|
||||||
- Michele Bologna
|
- Michele Bologna
|
||||||
- Montak Oleg
|
- Montak Oleg
|
||||||
- Moritz Grauel
|
- Moritz Grauel
|
||||||
- Nate Eagleson
|
|
||||||
- Nate Fischer
|
- Nate Fischer
|
||||||
- Nathan Rajlich
|
- Nathan Rajlich
|
||||||
- Nick Campbell
|
- Nick Campbell
|
||||||
|
|
@ -227,25 +203,17 @@ Patches and Suggestions
|
||||||
- Oliver Kopp
|
- Oliver Kopp
|
||||||
- Orestis
|
- Orestis
|
||||||
- Peter Bittner
|
- Peter Bittner
|
||||||
- Piotr Górski
|
|
||||||
- Prayag Verma
|
- Prayag Verma
|
||||||
- Przemek Kitszel
|
- Przemek Kitszel
|
||||||
- R. Martinho Fernandes
|
- R. Martinho Fernandes
|
||||||
- Raphael Fleischlin
|
- Raphael Fleischlin
|
||||||
- Rasmus Wriedt Larsen
|
- Rasmus Wriedt Larsen
|
||||||
- René
|
|
||||||
- Revisor
|
|
||||||
- Ricardo Fernández Serrata
|
|
||||||
- Riceball LEE
|
- Riceball LEE
|
||||||
- Rob Kennedy
|
- Rob Kennedy
|
||||||
- Robin von Bülow
|
- Robin von Bülow
|
||||||
- Russ
|
|
||||||
- Ryan Bohn
|
- Ryan Bohn
|
||||||
- Sachin Gupta
|
- Sachin Gupta
|
||||||
- Sam Thursfield
|
- Sam Thursfield
|
||||||
- Sandro
|
|
||||||
- Sascha Andres
|
|
||||||
- SchleimKeim
|
|
||||||
- Sean Molenaar
|
- Sean Molenaar
|
||||||
- Sebastian Gniazdowski
|
- Sebastian Gniazdowski
|
||||||
- Sebastián Mancilla
|
- Sebastián Mancilla
|
||||||
|
|
@ -254,7 +222,6 @@ Patches and Suggestions
|
||||||
- Stephen Mathieson
|
- Stephen Mathieson
|
||||||
- Steve Mao
|
- Steve Mao
|
||||||
- Stu Feldt
|
- Stu Feldt
|
||||||
- SukkaW
|
|
||||||
- Tim Preston
|
- Tim Preston
|
||||||
- Timothy Hwang
|
- Timothy Hwang
|
||||||
- Tin Lai
|
- Tin Lai
|
||||||
|
|
@ -265,10 +232,6 @@ Patches and Suggestions
|
||||||
- TweeKane
|
- TweeKane
|
||||||
- Valérian Galliat
|
- Valérian Galliat
|
||||||
- Vitaly Chikunov
|
- Vitaly Chikunov
|
||||||
- Wei Lee
|
|
||||||
- Wei Wu
|
|
||||||
- Wen Sun
|
|
||||||
- Wiktor Żurawik
|
|
||||||
- Xavier Krantz
|
- Xavier Krantz
|
||||||
- Xiaopei Li
|
- Xiaopei Li
|
||||||
- Zeeshan Ahmed
|
- Zeeshan Ahmed
|
||||||
|
|
@ -277,20 +240,15 @@ Patches and Suggestions
|
||||||
- dead-horse
|
- dead-horse
|
||||||
- eszabpt
|
- eszabpt
|
||||||
- fengkx
|
- fengkx
|
||||||
- johnpyp
|
|
||||||
- jykntr
|
- jykntr
|
||||||
- kang
|
|
||||||
- meza
|
- meza
|
||||||
- neydroid
|
- neydroid
|
||||||
- nulltask
|
- nulltask
|
||||||
- phanium
|
|
||||||
- sgleizes
|
- sgleizes
|
||||||
- tfendin
|
- tfendin
|
||||||
- tiemonl
|
- tiemonl
|
||||||
- zentarul
|
- zentarul
|
||||||
- zeroDivisible
|
- zeroDivisible
|
||||||
- zhiyanfoo
|
|
||||||
- Áron Hoffmann
|
|
||||||
- Étienne BERSAC
|
- Étienne BERSAC
|
||||||
- ☃ pitr
|
- ☃ pitr
|
||||||
- 单元源
|
- 单元源
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,15 @@
|
||||||
# Contributing
|
## Your new git-extra command should support
|
||||||
|
|
||||||
Thanks for contributing! Please read this document before you make a PR.
|
* OSX, Linux, BSD (You may need to browse their man page)<sup>*</sup>
|
||||||
|
* Bash 3.2+ (If you aren't sure, see [the Bash changelog](https://www.tldp.org/LDP/abs/html/bash2.html))
|
||||||
|
* Git 2.1+
|
||||||
|
|
||||||
## Supported Platforms
|
<sup>*</sup>If you aren't able to test your new command on a platform,
|
||||||
|
make that clear in your PR and someone else may be able to test it on their system.
|
||||||
|
|
||||||
Any changes must support the following platforms:
|
## To submit a new command, you should
|
||||||
|
|
||||||
- macOS
|
Let's assume your new command is named `foo`.
|
||||||
- Linux
|
|
||||||
- OpenBSD (You may need to browse their man page)
|
|
||||||
|
|
||||||
Your change must also be compatible with the dependency constraints that we specify in [Installation](./Installation.md). If you aren't sure if a feature is compatible, check the manual or release notes. For example, the Bash changelog is [here](https://git.savannah.gnu.org/cgit/bash.git/tree/NEWS?h=devel).
|
|
||||||
|
|
||||||
If you aren't able to test your new command on a platform, make that clear in your PR; someone else may be able to test it on their system.
|
|
||||||
|
|
||||||
## Adding a New Command
|
|
||||||
|
|
||||||
Let's say you wish to add a new command. Assuming your new command is named `foo`:
|
|
||||||
|
|
||||||
1. Write a bash script under `./bin` called `git-foo`. The script should be started with `#!/usr/bin/env bash`.
|
1. Write a bash script under `./bin` called `git-foo`. The script should be started with `#!/usr/bin/env bash`.
|
||||||
2. Read `./man/Readme.md` and write documentation for `git-foo`.
|
2. Read `./man/Readme.md` and write documentation for `git-foo`.
|
||||||
|
|
@ -24,11 +17,6 @@ Let's say you wish to add a new command. Assuming your new command is named `foo
|
||||||
4. Update `./etc/git-extras-completion.zsh`. Just follow existing code.
|
4. Update `./etc/git-extras-completion.zsh`. Just follow existing code.
|
||||||
5. (Optional) Update `./etc/bash_completion.sh`.
|
5. (Optional) Update `./etc/bash_completion.sh`.
|
||||||
6. (Optional) Update `./etc/git-extras.fish`.
|
6. (Optional) Update `./etc/git-extras.fish`.
|
||||||
7. (Optional) Add a test under `./tests`.
|
7. Run `./check_integrity.sh foo` to check if all done.
|
||||||
8. Run `./check_integrity.sh foo` to check if all done. (You may also run `./check_integrity.sh` to check all commands.)
|
|
||||||
|
|
||||||
You are welcome to open up an issue to discuss new commands or features before opening a pull request.
|
You are welcome to open up an issue to discuss new commands or features before opening a pull request.
|
||||||
|
|
||||||
## Submitting a pull request
|
|
||||||
|
|
||||||
Please follow the suggestion in `./.github/PULL_REQUEST_TEMPLATE.md`.
|
|
||||||
|
|
|
||||||
224
Commands.md
224
Commands.md
|
|
@ -12,13 +12,11 @@
|
||||||
- [`git clear-soft`](#git-clear-soft)
|
- [`git clear-soft`](#git-clear-soft)
|
||||||
- [`git coauthor`](#git-coauthor)
|
- [`git coauthor`](#git-coauthor)
|
||||||
- [`git commits-since`](#git-commits-since)
|
- [`git commits-since`](#git-commits-since)
|
||||||
- [`git continue`](#git-continue)
|
|
||||||
- [`git contrib`](#git-contrib)
|
- [`git contrib`](#git-contrib)
|
||||||
- [`git count`](#git-count)
|
- [`git count`](#git-count)
|
||||||
- [`git cp`](#git-cp)
|
- [`git cp`](#git-cp)
|
||||||
- [`git create-branch`](#git-create-branch)
|
- [`git create-branch`](#git-create-branch)
|
||||||
- [`git delete-branch`](#git-delete-branch)
|
- [`git delete-branch`](#git-delete-branch)
|
||||||
- [`git delete-gone-branches`](#git-delete-gone-branches)
|
|
||||||
- [`git delete-merged-branches`](#git-delete-merged-branches)
|
- [`git delete-merged-branches`](#git-delete-merged-branches)
|
||||||
- [`git delete-squashed-branches`](#git-delete-squashed-branches)
|
- [`git delete-squashed-branches`](#git-delete-squashed-branches)
|
||||||
- [`git delete-submodule`](#git-delete-submodule)
|
- [`git delete-submodule`](#git-delete-submodule)
|
||||||
|
|
@ -30,7 +28,6 @@
|
||||||
- [`git force-clone`](#git-force-clone)
|
- [`git force-clone`](#git-force-clone)
|
||||||
- [`git fork`](#git-fork)
|
- [`git fork`](#git-fork)
|
||||||
- [`git fresh-branch`](#git-fresh-branch)
|
- [`git fresh-branch`](#git-fresh-branch)
|
||||||
- [`git get`](#git-get)
|
|
||||||
- [`git gh-pages`](#git-gh-pages)
|
- [`git gh-pages`](#git-gh-pages)
|
||||||
- [`git graft`](#git-graft)
|
- [`git graft`](#git-graft)
|
||||||
- [`git guilt`](#git-guilt)
|
- [`git guilt`](#git-guilt)
|
||||||
|
|
@ -54,7 +51,6 @@
|
||||||
- [`git rebase-patch`](#git-rebase-patch)
|
- [`git rebase-patch`](#git-rebase-patch)
|
||||||
- [`git release`](#git-release)
|
- [`git release`](#git-release)
|
||||||
- [`git rename-branch`](#git-rename-branch)
|
- [`git rename-branch`](#git-rename-branch)
|
||||||
- [`git rename-file`](#git-rename-file)
|
|
||||||
- [`git rename-tag`](#git-rename-tag)
|
- [`git rename-tag`](#git-rename-tag)
|
||||||
- [`git rename-remote`](#git-rename-remote)
|
- [`git rename-remote`](#git-rename-remote)
|
||||||
- [`git repl`](#git-repl)
|
- [`git repl`](#git-repl)
|
||||||
|
|
@ -76,8 +72,6 @@
|
||||||
- [`git undo`](#git-undo)
|
- [`git undo`](#git-undo)
|
||||||
- [`git unlock`](#git-unlock)
|
- [`git unlock`](#git-unlock)
|
||||||
- [`git utimes`](#git-utimes)
|
- [`git utimes`](#git-utimes)
|
||||||
- [`git unwip`](#git-unwip)
|
|
||||||
- [`git wip`](#git-wip)
|
|
||||||
|
|
||||||
## git extras
|
## git extras
|
||||||
|
|
||||||
|
|
@ -157,15 +151,12 @@ Outputs a repo or path summary:
|
||||||
```bash
|
```bash
|
||||||
$ git summary
|
$ git summary
|
||||||
|
|
||||||
project : git-extras
|
project : git-extras
|
||||||
repo age : 10 months ago
|
repo age : 10 months ago
|
||||||
branch : master
|
commits : 163
|
||||||
last active : 3 weeks ago
|
active : 60 days
|
||||||
active on : 93 days
|
files : 93
|
||||||
commits : 163
|
authors :
|
||||||
files : 93
|
|
||||||
uncommitted : 3
|
|
||||||
authors :
|
|
||||||
97 Tj Holowaychuk 59.5%
|
97 Tj Holowaychuk 59.5%
|
||||||
37 Jonhnny Weslley 22.7%
|
37 Jonhnny Weslley 22.7%
|
||||||
8 Kenneth Reitz 4.9%
|
8 Kenneth Reitz 4.9%
|
||||||
|
|
@ -182,8 +173,8 @@ authors :
|
||||||
1 Guillermo Rauch 0.6%
|
1 Guillermo Rauch 0.6%
|
||||||
```
|
```
|
||||||
|
|
||||||
This command can also take a *committish*, and will print a summary for commits in
|
This command can also take a *commitish*, and will print a summary for commits in
|
||||||
the committish range:
|
the commitish range:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git summary v42..
|
$ git summary v42..
|
||||||
|
|
@ -228,18 +219,6 @@ project : git-extras
|
||||||
|
|
||||||
The `--line` option can also take a path, which will print a filtered summary for that folder or file.
|
The `--line` option can also take a path, which will print a filtered summary for that folder or file.
|
||||||
|
|
||||||
The option `--output-style` tries to put as much summary information of the repo into defined styled way as possible.
|
|
||||||
This is how the `tabular` output style and `oneline` output style look like
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git summary --output-style tabular
|
|
||||||
# Repo | Age | Last active | Active on | Commits | Uncommitted | Branch
|
|
||||||
git-extras | 13 years | 7 hours ago | 807 days | 1703 | 3 | master
|
|
||||||
|
|
||||||
$ git summary --output-style oneline
|
|
||||||
git-extras / age: 13 years / last active: 7 hours ago / active on 807 days / commits: 1703 / uncommitted: 3 / branch: master
|
|
||||||
```
|
|
||||||
|
|
||||||
## git effort
|
## git effort
|
||||||
|
|
||||||
Displays "effort" statistics, currently just the number of commits per file, showing highlighting where the most activity is. The "active days" column is the total number of days which contributed modifications to this file.
|
Displays "effort" statistics, currently just the number of commits per file, showing highlighting where the most activity is. The "active days" column is the total number of days which contributed modifications to this file.
|
||||||
|
|
@ -283,20 +262,11 @@ usage: git bulk [-g] ([-a]|[-w <ws-name>]) <git command>
|
||||||
git bulk --listall
|
git bulk --listall
|
||||||
```
|
```
|
||||||
|
|
||||||
Register a workspace so that `git bulk` knows about it (it will be registered in your `.gitconfig`):
|
Register a workspace so that `git bulk` knows about it (notice that <ws-root-directory> must be absolute path):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git bulk --addworkspace personal ~/workspaces/personal
|
$ git bulk --addworkspace personal ~/workspaces/personal
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice that `<ws-root-directory>` must be an absolute path (or an environment variable pointing to an absolute path).
|
|
||||||
In the case of a **single quoted environment variable**, it will be dereferenced at `git-bulk` runtime, suitable for dynamic workspaces (*e.g.*, defined in your `.bashrc`).
|
|
||||||
As an illustration:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git bulk --addworkspace personal '$PERSONAL_WORKSPACE'
|
|
||||||
```
|
|
||||||
|
|
||||||
With option `--from` the URL to a single repository or a file containing multiple URLs can be added and they will be cloned directly into the workspace. Suitable for the initial setup of a multi-repo project.
|
With option `--from` the URL to a single repository or a file containing multiple URLs can be added and they will be cloned directly into the workspace. Suitable for the initial setup of a multi-repo project.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -373,13 +343,6 @@ $ git brv
|
||||||
2020-01-08 master origin/master 265b03e Merge pull request #816 from spacewander/git-sed-pathspec
|
2020-01-08 master origin/master 265b03e Merge pull request #816 from spacewander/git-sed-pathspec
|
||||||
```
|
```
|
||||||
|
|
||||||
When your repo has many branches, it can be more convenient to see this list in reverse. This can be set as the default by setting the git-extras.brv.reverse git option to true.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git brv --reverse
|
|
||||||
2020-01-08 master origin/master 265b03e Merge pull request #816 from spacewander/git-sed-pathspec
|
|
||||||
2020-01-14 adds-git-brv fork/adds-git-brv 1ca0d76 Fixes #700: Adds git-brv
|
|
||||||
```
|
|
||||||
|
|
||||||
## git repl
|
## git repl
|
||||||
|
|
||||||
|
|
@ -388,53 +351,14 @@ Git read-eval-print-loop. Lets you run `git` commands without typing 'git'.
|
||||||
Commands can be prefixed with an exclamation mark (!) to be interpreted as
|
Commands can be prefixed with an exclamation mark (!) to be interpreted as
|
||||||
a regular command.
|
a regular command.
|
||||||
|
|
||||||
Type `exit`, `quit`, or `q` to end the repl session.
|
Type `exit` or `quit` to end the repl session.
|
||||||
|
|
||||||
Any arguments to git repl will be taken as the first command to execute in
|
|
||||||
the repl.
|
|
||||||
|
|
||||||
### CONFIGURATION
|
|
||||||
|
|
||||||
Commands entered in a repl session will be saved to a history file and be available in
|
|
||||||
future sessions, similar to a shell or programming language repl. By default,
|
|
||||||
there is one global history file, ~/.git_repl_history. You can specify that your projects
|
|
||||||
each have their own independent history file. This file will be saved in .git_repl_history
|
|
||||||
at the top level of the repo, and will need to be added to the repo or global .gitignore.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# remove the --global flag to configure only an individual project to have its own history file
|
|
||||||
git config --global git-extras.repl.use-local-history "true"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can specify a default command to run when hitting enter:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global git-extras.repl.on-enter-command "git status -sb"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can configure which character is used at the end of the prompt: (default `>`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global git-extras.repl.prompt-character "±"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can specify the prefix for the prompt, or remove it (default `git`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global git-extras.repl.prefix ""
|
|
||||||
```
|
|
||||||
|
|
||||||
You can have the name of the current git repo shown in the prompt (default `false`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git config --global git-extras.repl.show-project-name "true"
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git repl
|
$ git repl
|
||||||
git version 2.34.1
|
git version 2.9.2
|
||||||
git-extras version 7.3.0
|
git-extras version 3.0.0
|
||||||
Type 'ls' to ls files below current directory; '!command' to execute any command or just 'subcommand' to execute any git subcommand; 'quit', 'exit', 'q', ^D, or ^C to exit the git repl.
|
type 'ls' to ls files below current directory,
|
||||||
|
'!command' to execute any command or just 'subcommand' to execute any git subcommand
|
||||||
|
|
||||||
git (master)> ls-files
|
git (master)> ls-files
|
||||||
History.md
|
History.md
|
||||||
|
|
@ -465,9 +389,9 @@ $ git coauthor user user@email.com
|
||||||
2 files changed, 145 insertions(+), 0 deletions(-)
|
2 files changed, 145 insertions(+), 0 deletions(-)
|
||||||
create mode 100644 README.md
|
create mode 100644 README.md
|
||||||
create mode 100644 CONTRIBUTING.md
|
create mode 100644 CONTRIBUTING.md
|
||||||
|
|
||||||
$ git log -1
|
$ git log -1
|
||||||
|
|
||||||
commit b62ceae2685e6ece071f3c3754e9b77fd0a35c88 (HEAD -> master)
|
commit b62ceae2685e6ece071f3c3754e9b77fd0a35c88 (HEAD -> master)
|
||||||
Author: user person <userperson@email.com>
|
Author: user person <userperson@email.com>
|
||||||
Date: Sat Aug 17 17:33:53 2019 -0500
|
Date: Sat Aug 17 17:33:53 2019 -0500
|
||||||
|
|
@ -612,20 +536,6 @@ $ git rename-branch old-name new-name
|
||||||
$ git rename-branch new-name
|
$ git rename-branch new-name
|
||||||
```
|
```
|
||||||
|
|
||||||
## git rename-file
|
|
||||||
|
|
||||||
Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
|
||||||
It combines the functionality of the `mv` command and `git mv`. This is particularly useful for renaming files or directories
|
|
||||||
to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Rename a file
|
|
||||||
git rename-file old_filename new_filename
|
|
||||||
|
|
||||||
# Rename a directory
|
|
||||||
git rename-file old_directory new_directory
|
|
||||||
```
|
|
||||||
|
|
||||||
## git rename-tag
|
## git rename-tag
|
||||||
|
|
||||||
Rename a tag (locally and remotely).
|
Rename a tag (locally and remotely).
|
||||||
|
|
@ -774,14 +684,14 @@ build
|
||||||
|
|
||||||
## git ignore-io
|
## git ignore-io
|
||||||
|
|
||||||
Generate sample gitignore file from [gitignore.io](https://www.toptal.com/developers/gitignore)
|
Generate sample gitignore file from [gitignore.io](https://www.gitignore.io)
|
||||||
|
|
||||||
Without option, `git ignore-io <type>` shows the sample gitignore of specified types on screen.
|
Without option, `git ignore-io <type>` shows the sample gitignore of specified types on screen.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git ignore-io vim
|
$ git ignore-io vim
|
||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/vim
|
# Created by https://www.gitignore.io/api/vim
|
||||||
|
|
||||||
### Vim ###
|
### Vim ###
|
||||||
[._]*.s[a-w][a-z]
|
[._]*.s[a-w][a-z]
|
||||||
|
|
@ -933,21 +843,6 @@ Delete local and remote tag `name`:
|
||||||
$ git delete-tag 0.0.1
|
$ git delete-tag 0.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
## git delete-gone-branches
|
|
||||||
|
|
||||||
Deletes all local branches whose remote-tracking branch has been deleted (i.e. branches shown as `[gone]` in `git branch -vv`). Use `--dry-run` to preview what would be deleted.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git delete-gone-branches
|
|
||||||
Deleted branch feature-123 (was abc1234).
|
|
||||||
Deleted branch feature-456 (was def5678).
|
|
||||||
|
|
||||||
$ git delete-gone-branches --dry-run
|
|
||||||
Would delete the following branches:
|
|
||||||
feature-123
|
|
||||||
feature-456
|
|
||||||
```
|
|
||||||
|
|
||||||
## git delete-merged-branches
|
## git delete-merged-branches
|
||||||
|
|
||||||
Deletes branches that are listed in `git branch --merged`.
|
Deletes branches that are listed in `git branch --merged`.
|
||||||
|
|
@ -973,21 +868,12 @@ $ (main) git ...
|
||||||
|
|
||||||
## git fresh-branch
|
## git fresh-branch
|
||||||
|
|
||||||
Create empty local branch `docs`:
|
Create empty local branch `name`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git fresh-branch docs
|
$ git fresh-branch docs
|
||||||
```
|
```
|
||||||
|
|
||||||
## git get
|
|
||||||
|
|
||||||
Clone repository into a subdirectory of the configured path, `"$HOME/some-dir"`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git config --global --add git-extras.get.clone-path "$HOME/some-dir"
|
|
||||||
$ git get 'https://github.com/hyperupcall/bake'
|
|
||||||
```
|
|
||||||
|
|
||||||
## git guilt
|
## git guilt
|
||||||
|
|
||||||
Calculate the change in blame between two revisions
|
Calculate the change in blame between two revisions
|
||||||
|
|
@ -1042,6 +928,8 @@ $ git squash HEAD~3 "Work on a feature"
|
||||||
|
|
||||||
Populates the file matching `authors|contributors -i` with the authors of commits, according to the number of commits per author.
|
Populates the file matching `authors|contributors -i` with the authors of commits, according to the number of commits per author.
|
||||||
|
|
||||||
|
Opens the file in `$EDITOR` when set.
|
||||||
|
|
||||||
See the ["MAPPING AUTHORS" section](https://git-scm.com/docs/git-shortlog#_mapping_authors) of **git-shortlog**(1) to coalesce together commits by the same person.
|
See the ["MAPPING AUTHORS" section](https://git-scm.com/docs/git-shortlog#_mapping_authors) of **git-shortlog**(1) to coalesce together commits by the same person.
|
||||||
|
|
||||||
Updating AUTHORS file:
|
Updating AUTHORS file:
|
||||||
|
|
@ -1203,14 +1091,6 @@ Internally this script uses `rsync` and not `scp` as the name suggests.
|
||||||
|
|
||||||
`git-rscp` - The reverse of `git-scp`. Copies specific files from the working directory of a remote repository to the current working directory.
|
`git-rscp` - The reverse of `git-scp`. Copies specific files from the working directory of a remote repository to the current working directory.
|
||||||
|
|
||||||
The following options are available (must precede `<remote>`):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
-v, --verbose Print what will be synced before syncing
|
|
||||||
-i, --interactive Prompt for confirmation before syncing (implies --verbose)
|
|
||||||
-n, --dry-run Show what would be synced, change nothing (implies --verbose)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
Copy unstaged files to remote. Useful when you want to make quick test without making any commits
|
Copy unstaged files to remote. Useful when you want to make quick test without making any commits
|
||||||
|
|
@ -1371,7 +1251,7 @@ Creates a zip archive of the current git repository. The name of the archive wil
|
||||||
|
|
||||||
## git missing
|
## git missing
|
||||||
|
|
||||||
Print out which commits are on one branch or the other but not both. Optionally, you can specify a path to limit the comparison to a specific directory or file.
|
Print out which commits are on one branch or the other but not both.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git missing master
|
$ git missing master
|
||||||
|
|
@ -1379,12 +1259,6 @@ $ git missing master
|
||||||
> 97ef387 only on master
|
> 97ef387 only on master
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git missing master -- src/
|
|
||||||
< ed52989 only on current branch, in src/ directory
|
|
||||||
> 7988c4b only on master, in src/ directory
|
|
||||||
```
|
|
||||||
|
|
||||||
## git lock
|
## git lock
|
||||||
|
|
||||||
Lock a local file `filename`:
|
Lock a local file `filename`:
|
||||||
|
|
@ -1428,8 +1302,8 @@ $ git reset-file .htaccess dc82b19
|
||||||
|
|
||||||
## git mr
|
## git mr
|
||||||
|
|
||||||
Checks out a merge request from GitLab, or a pull request from Forgejo/Codeberg.
|
Checks out a merge request from GitLab. Usage: `git mr <ID|URL> [REMOTE]`.
|
||||||
Usage: `git mr <ID|URL> [REMOTE]`. Default remote is `origin`.
|
Default remote is `origin`.
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
$ git mr 51
|
$ git mr 51
|
||||||
|
|
@ -1441,21 +1315,12 @@ Switched to branch 'mr/51'
|
||||||
With full URL, the head is fetched from a temporary remote pointing to the base URL.
|
With full URL, the head is fetched from a temporary remote pointing to the base URL.
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
$ git mr https://gitlab.com/owner/repository/merge_requests/51
|
$ git mr https://gitlab.com/owner/repository/merge_requests/51
|
||||||
From gitlab.com:owner/repository
|
From gitlab.com:owner/repository
|
||||||
* [new ref] refs/merge-requests/51/head -> mr/51
|
* [new ref] refs/merge-requests/51/head -> mr/51
|
||||||
Switched to branch 'mr/51'
|
Switched to branch 'mr/51'
|
||||||
```
|
```
|
||||||
|
|
||||||
A Forgejo/Codeberg pull request URL is also supported:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ git mr https://codeberg.org/owner/repository/pulls/51
|
|
||||||
From codeberg.org:owner/repository
|
|
||||||
* [new ref] refs/pull/51/head -> mr/51
|
|
||||||
Switched to branch 'mr/51'
|
|
||||||
```
|
|
||||||
|
|
||||||
Just like [git pr](#git-pr), `git mr` accepts a `clean` argument to trash all
|
Just like [git pr](#git-pr), `git mr` accepts a `clean` argument to trash all
|
||||||
`mr/` branches. Ensure current branch is not one.
|
`mr/` branches. Ensure current branch is not one.
|
||||||
|
|
||||||
|
|
@ -1655,14 +1520,12 @@ $ git browse-ci upstream
|
||||||
|
|
||||||
## git utimes
|
## git utimes
|
||||||
|
|
||||||
Change files modification time to their last commit date. Does not touch files that are in the working tree or index.
|
Change files modification time to their last commit date.
|
||||||
|
|
||||||
The `--newer` flag preserves the original modification time of files that were committed from the local repo, by only touching files that are newer than their last commit date.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git-extras$ ls -l bin | head
|
git-extras$ ls -l bin | head
|
||||||
total 308
|
total 308
|
||||||
-rwxr-xr-x 1 vt vt 489 Jul 28 2015 git-alias
|
-rwxr-xr-x 1 vt vt 489 Nov 8 13:56 git-alias
|
||||||
-rwxr-xr-x 1 vt vt 1043 Nov 8 13:56 git-archive-file
|
-rwxr-xr-x 1 vt vt 1043 Nov 8 13:56 git-archive-file
|
||||||
-rwxr-xr-x 1 vt vt 970 Nov 8 13:56 git-authors
|
-rwxr-xr-x 1 vt vt 970 Nov 8 13:56 git-authors
|
||||||
-rwxr-xr-x 1 vt vt 267 Nov 8 13:56 git-back
|
-rwxr-xr-x 1 vt vt 267 Nov 8 13:56 git-back
|
||||||
|
|
@ -1671,8 +1534,8 @@ total 308
|
||||||
-rwxr-xr-x 1 vt vt 6282 Nov 8 13:56 git-bulk
|
-rwxr-xr-x 1 vt vt 6282 Nov 8 13:56 git-bulk
|
||||||
-rwxr-xr-x 1 vt vt 18561 Nov 8 13:56 git-changelog
|
-rwxr-xr-x 1 vt vt 18561 Nov 8 13:56 git-changelog
|
||||||
-rwxr-xr-x 1 vt vt 215 Nov 8 13:56 git-clear
|
-rwxr-xr-x 1 vt vt 215 Nov 8 13:56 git-clear
|
||||||
|
git-extras$ git utimes
|
||||||
git-extras$ git utimes --newer
|
+ touch -d 2015-08-09T19:27:49+08:00 bin/git-alias
|
||||||
+ touch -d 2020-05-22T10:40:29+08:00 bin/git-archive-file
|
+ touch -d 2020-05-22T10:40:29+08:00 bin/git-archive-file
|
||||||
+ touch -d 2017-05-05T16:02:09+08:00 bin/git-authors
|
+ touch -d 2017-05-05T16:02:09+08:00 bin/git-authors
|
||||||
+ touch -d 2020-02-23T11:41:54+08:00 bin/git-back
|
+ touch -d 2020-02-23T11:41:54+08:00 bin/git-back
|
||||||
|
|
@ -1682,10 +1545,9 @@ git-extras$ git utimes --newer
|
||||||
+ touch -d 2019-09-05T12:41:38+08:00 bin/git-changelog
|
+ touch -d 2019-09-05T12:41:38+08:00 bin/git-changelog
|
||||||
+ touch -d 2016-11-19T16:41:19+00:00 bin/git-clear
|
+ touch -d 2016-11-19T16:41:19+00:00 bin/git-clear
|
||||||
[...]
|
[...]
|
||||||
|
|
||||||
git-extras$ ls -l bin | head
|
git-extras$ ls -l bin | head
|
||||||
total 308
|
total 308
|
||||||
-rwxr-xr-x 1 vt vt 489 Jul 28 2015 git-alias
|
-rwxr-xr-x 1 vt vt 489 Aug 9 2015 git-alias
|
||||||
-rwxr-xr-x 1 vt vt 1043 May 22 05:40 git-archive-file
|
-rwxr-xr-x 1 vt vt 1043 May 22 05:40 git-archive-file
|
||||||
-rwxr-xr-x 1 vt vt 970 May 5 2017 git-authors
|
-rwxr-xr-x 1 vt vt 970 May 5 2017 git-authors
|
||||||
-rwxr-xr-x 1 vt vt 267 Feb 23 2020 git-back
|
-rwxr-xr-x 1 vt vt 267 Feb 23 2020 git-back
|
||||||
|
|
@ -1696,34 +1558,10 @@ total 308
|
||||||
-rwxr-xr-x 1 vt vt 215 Nov 19 2016 git-clear
|
-rwxr-xr-x 1 vt vt 215 Nov 19 2016 git-clear
|
||||||
```
|
```
|
||||||
|
|
||||||
Note above, that because of the `--newer` flag, the file `git-alias` was not touched since its modified date is earlier than the commit date.
|
|
||||||
|
|
||||||
## git abort
|
## git abort
|
||||||
|
|
||||||
Abort current revert, rebase, merge or cherry-pick, without the need to find exact command in history.
|
Abort current rebase, merge or cherry-pick, without the need to find exact command in history.
|
||||||
|
|
||||||
## git magic
|
## git magic
|
||||||
|
|
||||||
Commits changes with a generated message.
|
Commits changes with a generated message.
|
||||||
|
|
||||||
## git continue
|
|
||||||
|
|
||||||
Continue current revert, rebase, merge or cherry-pick, without the need to find exact command in history.
|
|
||||||
|
|
||||||
## git wip
|
|
||||||
|
|
||||||
Create a Work In Progress(WIP) commit, which will include all changes in the
|
|
||||||
working directory. (i.e., changes to existing files, new files, removed files)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git wip
|
|
||||||
```
|
|
||||||
|
|
||||||
## git unwip
|
|
||||||
|
|
||||||
Undo a Work In Progress(WIP) commit and put all of those changes back into the
|
|
||||||
working directory.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git unwip
|
|
||||||
```
|
|
||||||
|
|
|
||||||
206
History.md
206
History.md
|
|
@ -1,209 +1,3 @@
|
||||||
|
|
||||||
7.5.0 / 2026-05-09
|
|
||||||
==================
|
|
||||||
|
|
||||||
* Use standard prefix for home dir installs (#1248)
|
|
||||||
* refactor(abort): common `gitdir` (#1244)
|
|
||||||
* Fix man page usage docs (#1241)
|
|
||||||
* Fix `git-changelog` to handle whitespace in command arguments (#1232)
|
|
||||||
* chore(deps): bump bats-core/bats-action from 3.0.1 to 4.0.0 (#1230)
|
|
||||||
* add details when multiple active operations found (#1229)
|
|
||||||
* Add persistent history to `git-repl` (#1226)
|
|
||||||
* Support passing ref to `git-commits-since` (#1228)
|
|
||||||
* ability to specify command when hitting enter (#1223)
|
|
||||||
* Improve `git-repl` prompt (#1224)
|
|
||||||
* feat: `delete-branch` multiple unique branch names completions (#1221)
|
|
||||||
* chore(deps): bump actions/checkout from 5 to 6 (#1219)
|
|
||||||
* Made Git Magic use `--force-with-lease` (#1218)
|
|
||||||
* chore(deps): bump actions/stale from 9 to 10 (#1214)
|
|
||||||
* chore(deps): bump actions/setup-go from 5 to 6 (#1215)
|
|
||||||
* chore(deps): bump actions/setup-python from 5 to 6 (#1216)
|
|
||||||
* Fix minor typo in `git rename-branch` man page (#1211)
|
|
||||||
* Improvements to Bash completion (#1210)
|
|
||||||
* Fix use of `git-whatchanged` to `git-log` (#1212)
|
|
||||||
* chore(deps): bump actions/checkout from 4 to 5 (#1209)
|
|
||||||
* Bump version to 7.5.0-dev (#1207)
|
|
||||||
|
|
||||||
7.4.0 / 2025-06-19
|
|
||||||
==================
|
|
||||||
|
|
||||||
* Format comparisons, functions, and redirections to be consistent (#1201)
|
|
||||||
* add git-wip and git-unwip (#669)
|
|
||||||
* chore(deps): bump bats-core/bats-action from 3.0.0 to 3.0.1
|
|
||||||
* Mostly finish pytest to Bats conversion (#1200)
|
|
||||||
* Implement half of tests in Bats (#1187)
|
|
||||||
* Add stale bot for old PRs (#1186)
|
|
||||||
* feat(git-bulk): add new option to not follow hidden directories (#1195)
|
|
||||||
* Feat: allow git-summary showing full path of repository (#1193)
|
|
||||||
* feat(git-bulk): add new option to no follow symlinks (#1194)
|
|
||||||
* docs(git-bulk): Add zsh completion (#1190)
|
|
||||||
* fix(git-bulk): fix workspace selection when cd fails (#1197)
|
|
||||||
* fix(git-bulk): quiet find errors by default (#1196)
|
|
||||||
* fix(git-bulk): fix a bad integer expression (#1198)
|
|
||||||
* chore(deps): bump astral-sh/ruff-action from 2 to 3 (#1189)
|
|
||||||
* Fix all ShellCheck errors and add to CI (#1179)
|
|
||||||
* chore(deps): bump astral-sh/ruff-action from 1 to 2 (#1188)
|
|
||||||
* fix(ci): use poetry (#1183)
|
|
||||||
* Delete etc/test.fish (#1185)
|
|
||||||
* feat: add git-continue (#1176)
|
|
||||||
* feat: add ruff linter with ci check (#1182)
|
|
||||||
* fix(ci): missing dollar sign (#1184)
|
|
||||||
* fix(github-actions): changed files output for editorcondig-checker (#1180)
|
|
||||||
* Revert "feat: add ruff linter with ci check (#1178)" (#1181)
|
|
||||||
* feat: add ruff linter with ci check (#1178)
|
|
||||||
* Support `GITHUB_TOKEN` var for `git-fork` and `git-pull-request` (#1177)
|
|
||||||
* Bump version to 7.4.0-dev (#1175)
|
|
||||||
|
|
||||||
7.3.0 / 2024-10-20
|
|
||||||
==================
|
|
||||||
|
|
||||||
* Fix stripping trailing forward slash for git-get (#1172)
|
|
||||||
* Change git-cp to use cleaner branch approach (#1169)
|
|
||||||
* Improve warning for `git clear` (#1168)
|
|
||||||
* Enhance `git-repl` (#1160)
|
|
||||||
* Update some documentation that was out of sync (#1164)
|
|
||||||
* Use filetimes in check_integrity (#1162)
|
|
||||||
* Update git-alias.md: add brs to prevent incorrect line behavior (#1161)
|
|
||||||
* Update git-bulk.md: use correct stylization in synopsis (#1163)
|
|
||||||
* Update git-repl.md: typo: "let's" for "lets" (#1158)
|
|
||||||
* Update instructions for the OpenSUSE installation (#1157)
|
|
||||||
* Add pathspec support in `git-missing` (#1156)
|
|
||||||
* feat: add rename-file command (#1149)
|
|
||||||
* Update Commands.md (#1148)
|
|
||||||
* fix: git-summary commit count (#1147)
|
|
||||||
* tests: update dependencies (#1142)
|
|
||||||
* chore(deps): bump masesgroup/retrieve-changed-files from 2 to 3 (#1144)
|
|
||||||
* chore(deps): bump actions/setup-go from 4 to 5 (#1143)
|
|
||||||
* ci: add dependabot update for GitHub actions (#1141)
|
|
||||||
* ci: update actions (#1140)
|
|
||||||
* Bump version to 7.3.0-dev (#1139)
|
|
||||||
|
|
||||||
7.2.0 / 2024-04-21
|
|
||||||
==================
|
|
||||||
|
|
||||||
* refactor: test utils and simplify the case code (#1136)
|
|
||||||
* Add --proceed flag to git-delete-squashed-branches (#1134) (#1135)
|
|
||||||
* test(browse-ci): add unit tests (#1130)
|
|
||||||
* test(git-browse): add unit tests (#1127)
|
|
||||||
* feat: add reverse option to git-brv (#1123)
|
|
||||||
* fix(utimes): change /dev/stdin to -
|
|
||||||
* fix(utimes): Support filenames with backspaces, etc. (#1122)
|
|
||||||
* chore: add poetry to handle the tests of the git extras (#1121)
|
|
||||||
* Fix typo in ci.yml (#1120)
|
|
||||||
* Fix: harden utimes, use single quotes (#1109)
|
|
||||||
* Fix: patch git-utimes (fixes #1118) (#1119)
|
|
||||||
* add pull request manner (#1113)
|
|
||||||
* maintenance: Add my name as maintainer in AUTHORS (#1117)
|
|
||||||
* test(git-authors): add unit test (#1098)
|
|
||||||
* Add more comprensive dependencies (#1111)
|
|
||||||
* fix: git-standup find error (tj#1106) (#1110)
|
|
||||||
* Improve defaults for testing suite (#1104)
|
|
||||||
* feat: Speed up utimes (#1108)
|
|
||||||
* Overhaul CONTRIBUTING document (#1103)
|
|
||||||
* Bump version to 7.2.0-dev (#1099)
|
|
||||||
|
|
||||||
7.1.0 / 2023-10-28
|
|
||||||
==================
|
|
||||||
|
|
||||||
* git-cp: don't stop execution when merge.ff is not set (#1096)
|
|
||||||
* Allow `git cp` to create destination folder automatically (#1091)
|
|
||||||
* fix: Use `-iname` and expressions instead of `-iregex` (#1094)
|
|
||||||
* change installation source from master to main (#1092)
|
|
||||||
* test(git-archive-file): add unit test (#1084)
|
|
||||||
* ci: Use Go v1.20 for running `editorconfig-checker` (#1086)
|
|
||||||
* test(git-alias): add its unit test (#1077)
|
|
||||||
* makefile: Allow bypassing conflict check (#1080)
|
|
||||||
* fix: Restore zsh completions to working completion (#1079)
|
|
||||||
* fix: add missing quote in git-extras-completion.zsh (#1078)
|
|
||||||
* feat: Implement completion for `git coauthor` (#1074)
|
|
||||||
* fix: Move improvements via ShellCheck (#1075)
|
|
||||||
* feat(auto-test): CI with pytest (#1066)
|
|
||||||
* git-feature: add configurable branch separator (#1072)
|
|
||||||
* git-psykorebase: determine branch names with bash pattern substitution (#1073)
|
|
||||||
* git-cp: continue to merge when merge.ff is only (#1070)
|
|
||||||
* git archive-file: change base ARCHIVE_NAME (#1071)
|
|
||||||
* readme: Add secondary location of screencast (#1065)
|
|
||||||
* fix: Improve Bash hygiene (#1056)
|
|
||||||
* feat: Implement `git-get` command (#1045)
|
|
||||||
* Corrected grammar in bin/git-cp (#1061)
|
|
||||||
* Improve `git-ignore` command (#1047)
|
|
||||||
* I have made two improvements to the git-bulk: (#1054)
|
|
||||||
* Type properly `__gitex_command_successful` calls and capitalizate github to GitHub (#1049)
|
|
||||||
* Add typo checker
|
|
||||||
* Fix comment typo in git-authors (#1050)
|
|
||||||
* tweak: Fix typos (#1046)
|
|
||||||
* Makefile: init SYSCONFDIR before using it (#1044)
|
|
||||||
* Makefile: tune MANPREFIX configuration for FreeBSD (#1043)
|
|
||||||
* Makefile: set bash COMPL_DIR to FreeBSD expected defaults (#1042)
|
|
||||||
* Bump version to 7.1.0-dev (#1041)
|
|
||||||
|
|
||||||
7.0.0 / 2023-04-20
|
|
||||||
==================
|
|
||||||
|
|
||||||
* git-delete-tag: should not be quoted
|
|
||||||
* Add the current branch git summary (#1034)
|
|
||||||
* chore: Improve Bash variously (#1032)
|
|
||||||
* Change the oneline option to a tebular version in the git summary (#1031)
|
|
||||||
* chore: Remove `X`-style equality comparisons (#1028)
|
|
||||||
* chore: Various Bash improvements (#1029)
|
|
||||||
* fix: No longer pollute env with `GREP_OPTIONS`
|
|
||||||
* tweak editor config (#1027)
|
|
||||||
* revert the completion dir change on MacOS (#1026)
|
|
||||||
* Update gitignore.io urls to Toptal urls (#1025)
|
|
||||||
* Add EditorConfig file (#1022)
|
|
||||||
* Make the bulk output slimmer (#1020)
|
|
||||||
* chore: Fix more Bash inconsistencies (#1021)
|
|
||||||
* Repo status overview (#1017)
|
|
||||||
* Replace egrep with grep -E (#1019)
|
|
||||||
* chore: More Bash improvements and removing deprecations (#1016)
|
|
||||||
* chore: Improve quoting and builtin usage (#1015)
|
|
||||||
* Add summary fields (#1013)
|
|
||||||
* Fix quiet mode of the bulk command (#1014)
|
|
||||||
* git-summary: remove stray \ in grep call (#1010)
|
|
||||||
* Allow to run git-extras within git-bulk (#1008)
|
|
||||||
* Make git-summary accept multiple paths for the --lines argument (#1005)
|
|
||||||
* Makefile: ensure bash is used instead of /bin/sh (#1004)
|
|
||||||
* fix base branch in the pull-request command (#1003)
|
|
||||||
* Update docs for git abort change (#1000)
|
|
||||||
* Bump version to 6.6.0-dev (#997)
|
|
||||||
|
|
||||||
6.5.0 / 2022-10-06
|
|
||||||
==================
|
|
||||||
|
|
||||||
* git root: show '.' when using with -r in the root dir (#995)
|
|
||||||
* git standup: work as expected when no configured (#996)
|
|
||||||
* rephrase question depending on switch (#984)
|
|
||||||
* Include revert conflicts in git abort (#992)
|
|
||||||
* fix(git-effort):fork: retry: Resource temporarily unavailable #979 (#990)
|
|
||||||
* git-sync --force will sync without interaction (#989)
|
|
||||||
* fix(git-cp): keep the history of the files
|
|
||||||
* git-bulk: previous refactor redirected $PWD to stderr by mistake
|
|
||||||
* Fix lazy loading bash_completion from XDG_DATA_DIRS
|
|
||||||
* Minor changes to man/git-standup.md
|
|
||||||
* Replaced -g and -A with -F gpg|authordate
|
|
||||||
* fix(bin/git-browse): fix commit hash
|
|
||||||
* fix(bin/git-browse): fix bitbucket url
|
|
||||||
* feat: open website at file & line number or range
|
|
||||||
* #970 standup added -A flag for author date
|
|
||||||
* update docs due to formatting error in git-utimes man page
|
|
||||||
* update per shellcheck advice
|
|
||||||
* update git-utimes.{1,html} to add --newer flag
|
|
||||||
* Don't read git-extras.standup.implicit-week twice in git standup
|
|
||||||
* quote mod_s and git_s integer vars
|
|
||||||
* updates per request of spacewander
|
|
||||||
* Update Commands.md
|
|
||||||
* allow modification date updates for symbolic links
|
|
||||||
* add --newer flag and ignore files in the working tree or index
|
|
||||||
* Documented config git-extras.standup.implicit-week
|
|
||||||
* Minor change to git standup -w documentation
|
|
||||||
* Improved check if -w or -d was given to git standup
|
|
||||||
* Renamed config git-extras.standup.implicit-week from git-extras.standup-implicit-week
|
|
||||||
* Documented weekend behaviour of git standup -w
|
|
||||||
* docs(instllation): replace `git.io`
|
|
||||||
* Bump version to 6.5.0-dev
|
|
||||||
* Added config git-extras.standup-implicit-week for git standup
|
|
||||||
* Document git standup -w option
|
|
||||||
|
|
||||||
6.4.0 / 2022-04-22
|
6.4.0 / 2022-04-22
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,13 @@
|
||||||
# Installation
|
# Installing git-extras
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
Some commands require extra dependencies which are unavailable in some platforms.
|
Some commands require extra dependencies which are unavailable in some platforms.
|
||||||
You may need to install them manually. They are:
|
You may need to install them manually.
|
||||||
|
|
||||||
* bash 4.0+
|
Those dependencies are listed below:
|
||||||
* Git 2.17+
|
|
||||||
* `column`
|
|
||||||
* `awk`
|
|
||||||
* `find`
|
|
||||||
* `tput`
|
|
||||||
* cURL (only required for `git-fork`, `git-ignore-io`, `git-pull-request`)
|
|
||||||
* `ps` (only required for `git-changelog`)
|
|
||||||
* `rsync` (only required for `git-rscp`, `git-scp`)
|
|
||||||
* `xargs` (only required for `git-delete-merged-branches`, `git-force-clone`, `git-sed`, `git-scp`)
|
|
||||||
|
|
||||||
If `bash --version` shows a lower version, you need to update it.
|
* column
|
||||||
For example, the default bash in Mac is usually too old and you may need to update it via `brew install bash`.
|
|
||||||
|
|
||||||
## Installing with a package manager
|
## Installing with a package manager
|
||||||
|
|
||||||
|
|
@ -41,10 +31,9 @@ $ sudo dnf install git-extras
|
||||||
|
|
||||||
### openSUSE
|
### openSUSE
|
||||||
|
|
||||||
Substitute your openSUSE version in the command below (in this case we are considering openSUSE Leap 15.6):
|
Substitute your openSUSE version in the command below (in this case we are considering openSUSE Leap 15.2):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ sudo zypper ar https://download.opensuse.org/repositories/devel:/tools:/scm/15.6/devel:tools:scm.repo
|
$ sudo zypper ar https://download.opensuse.org/repositories/devel:/tools:/scm/openSUSE_Leap_15.2/devel:tools:scm.repo
|
||||||
```
|
```
|
||||||
|
|
||||||
and install it:
|
and install it:
|
||||||
|
|
@ -75,6 +64,7 @@ $ nix-env -i git-extras
|
||||||
|
|
||||||
[Abdullah](https://github.com/AWAN) has written a [Pkgfile](https://abdullah.today/ports/git-extras/Pkgfile) for his beloved [distro](https://crux.nu).
|
[Abdullah](https://github.com/AWAN) has written a [Pkgfile](https://abdullah.today/ports/git-extras/Pkgfile) for his beloved [distro](https://crux.nu).
|
||||||
|
|
||||||
|
|
||||||
### Homebrew
|
### Homebrew
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -83,6 +73,7 @@ $ brew install git-extras
|
||||||
|
|
||||||
Installing from Homebrew will not give you the option omit certain `git-extras` if they conflict with existing git aliases. To have this option, build from source.
|
Installing from Homebrew will not give you the option omit certain `git-extras` if they conflict with existing git aliases. To have this option, build from source.
|
||||||
|
|
||||||
|
|
||||||
### Arch Linux
|
### Arch Linux
|
||||||
|
|
||||||
* [git-extras](https://aur.archlinux.org/packages/git-extras/)
|
* [git-extras](https://aur.archlinux.org/packages/git-extras/)
|
||||||
|
|
@ -92,7 +83,6 @@ Installing from Homebrew will not give you the option omit certain `git-extras`
|
||||||
|
|
||||||
First, please install `Git for Windows 2.x` from 'https://github.com/git-for-windows/git/releases'.
|
First, please install `Git for Windows 2.x` from 'https://github.com/git-for-windows/git/releases'.
|
||||||
Second, clone the `git-extras` repo into any folder you like.
|
Second, clone the `git-extras` repo into any folder you like.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/tj/git-extras.git
|
git clone https://github.com/tj/git-extras.git
|
||||||
# checkout the latest tag (optional)
|
# checkout the latest tag (optional)
|
||||||
|
|
@ -144,7 +134,7 @@ alternate location, specify a `PREFIX` when calling `make`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Non-root users can install under their home directory
|
# Non-root users can install under their home directory
|
||||||
make install PREFIX=$HOME/.local
|
make install PREFIX=$HOME/software
|
||||||
|
|
||||||
# For third-party software kept under /opt
|
# For third-party software kept under /opt
|
||||||
make install PREFIX=/opt
|
make install PREFIX=/opt
|
||||||
|
|
@ -154,7 +144,7 @@ If you want to relocate the bulk of the installation but still have configuratio
|
||||||
files installed to the system `/etc` dir or other alternate location, you can
|
files installed to the system `/etc` dir or other alternate location, you can
|
||||||
specify `SYSCONFDIR` in addition to `PREFIX`.
|
specify `SYSCONFDIR` in addition to `PREFIX`.
|
||||||
|
|
||||||
```sh
|
```
|
||||||
$ sudo make install PREFIX=/usr/local SYSCONFDIR=/etc
|
$ sudo make install PREFIX=/usr/local SYSCONFDIR=/etc
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -165,13 +155,12 @@ See the Makefile for details on advanced configuration options.
|
||||||
One-liner:
|
One-liner:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sSL https://raw.githubusercontent.com/tj/git-extras/main/install.sh | sudo bash /dev/stdin
|
curl -sSL https://git.io/git-extras-setup | sudo bash /dev/stdin
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installing as Zsh plugin
|
## Installing as Zsh plugin
|
||||||
|
|
||||||
[ZInit](https://github.com/zdharma/zinit) can install git-extras by using:
|
[ZInit](https://github.com/zdharma/zinit) can install git-extras by using:
|
||||||
|
|
||||||
```zsh
|
```zsh
|
||||||
zinit ice as"program" pick"$ZPFX/bin/git-*" src"etc/git-extras-completion.zsh" make"PREFIX=$ZPFX"
|
zinit ice as"program" pick"$ZPFX/bin/git-*" src"etc/git-extras-completion.zsh" make"PREFIX=$ZPFX"
|
||||||
zinit light tj/git-extras
|
zinit light tj/git-extras
|
||||||
|
|
|
||||||
46
Makefile
46
Makefile
|
|
@ -1,25 +1,14 @@
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
BINPREFIX ?= "$(PREFIX)/bin"
|
BINPREFIX ?= "$(PREFIX)/bin"
|
||||||
SYSCONFDIR ?= $(PREFIX)/etc
|
|
||||||
SHELL := bash
|
|
||||||
|
|
||||||
OS = $(shell uname)
|
OS = $(shell uname)
|
||||||
ifeq ($(OS), FreeBSD)
|
ifeq ($(OS), FreeBSD)
|
||||||
MANPREFIX ?= "$(PREFIX)/man/man1"
|
MANPREFIX ?= "$(PREFIX)/man/man1"
|
||||||
ifeq ($(MANPREFIX), /usr/local)
|
|
||||||
MANPREFIX = "/usr/local/man/man1"
|
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
MANPREFIX ?= "$(PREFIX)/share/man/man1"
|
MANPREFIX ?= "$(PREFIX)/share/man/man1"
|
||||||
endif
|
endif
|
||||||
ifeq ($(OS), Darwin)
|
|
||||||
COMPL_DIR ?= "$(DESTDIR)$(SYSCONFDIR)/bash_completion.d"
|
|
||||||
else ifeq ($(OS), FreeBSD)
|
|
||||||
COMPL_DIR ?= "$(DESTDIR)$(SYSCONFDIR)/bash_completion.d"
|
|
||||||
else
|
|
||||||
COMPL_DIR ?= "$(DESTDIR)$(SYSCONFDIR)/bash-completion/completions"
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
SYSCONFDIR ?= $(PREFIX)/etc
|
||||||
BINS = $(wildcard bin/git-*)
|
BINS = $(wildcard bin/git-*)
|
||||||
MANS = $(wildcard man/git-*.md)
|
MANS = $(wildcard man/git-*.md)
|
||||||
MAN_BINS = $(filter-out man/git-extras.md, $(MANS))
|
MAN_BINS = $(filter-out man/git-extras.md, $(MANS))
|
||||||
|
|
@ -45,24 +34,22 @@ install: check
|
||||||
@if [ "$(INSTALL_VIA)" = brew ]; then \
|
@if [ "$(INSTALL_VIA)" = brew ]; then \
|
||||||
git apply brew-release.patch || { echo "Can't apply brew release patch"; exit 1; } \
|
git apply brew-release.patch || { echo "Can't apply brew release patch"; exit 1; } \
|
||||||
fi
|
fi
|
||||||
mkdir -p $(DESTDIR)$(MANPREFIX)
|
@mkdir -p $(DESTDIR)$(MANPREFIX)
|
||||||
mkdir -p $(DESTDIR)$(BINPREFIX)
|
@mkdir -p $(DESTDIR)$(BINPREFIX)
|
||||||
@echo '... installing bins to '$(DESTDIR)$(BINPREFIX)
|
@echo "... installing bins to $(DESTDIR)$(BINPREFIX)"
|
||||||
@echo '... installing man pages to '$(DESTDIR)$(MANPREFIX)
|
@echo "... installing man pages to $(DESTDIR)$(MANPREFIX)"
|
||||||
$(eval TEMPFILE := $(shell mktemp -q $${TMPDIR:-/tmp}/git-extras.XXXXXX 2>/dev/null || mktemp -q))
|
$(eval TEMPFILE := $(shell mktemp -q $${TMPDIR:-/tmp}/git-extras.XXXXXX 2>/dev/null || mktemp -q))
|
||||||
@# chmod from rw-------(default) to rwxrwxr-x, so that users can exec the scripts
|
@# chmod from rw-------(default) to rwxrwxr-x, so that users can exec the scripts
|
||||||
@chmod 775 $(TEMPFILE)
|
@chmod 775 $(TEMPFILE)
|
||||||
$(eval EXISTED_ALIASES := $(shell \
|
$(eval EXISTED_ALIASES := $(shell \
|
||||||
git config --get-regexp 'alias\..*' | awk '{print "git-" substr($$1, 7)}'))
|
git config --get-regexp 'alias.*' | awk '{print "git-" substr($$1, 7)}'))
|
||||||
@$(foreach COMMAND, $(COMMANDS), \
|
@$(foreach COMMAND, $(COMMANDS), \
|
||||||
should_install='yes'; \
|
disable=''; \
|
||||||
if [ ! -z "$(filter $(COMMAND), $(EXISTED_ALIASES))" ] && [ "$$SKIP_CONFLICT_CHECK" != yes ]; then \
|
if test ! -z "$(filter $(COMMAND), $(EXISTED_ALIASES))"; then \
|
||||||
read -p "$(COMMAND) conflicts with an alias, still install it? [y/n]: " answer; \
|
read -p "$(COMMAND) conflicts with an alias, still install it and disable the alias? [y/n]" answer; \
|
||||||
if [ "$$answer" = 'n' ] || [ "$$answer" = 'N' ]; then \
|
test "$$answer" = 'n' -o "$$answer" = 'N' && disable="true"; \
|
||||||
should_install="no"; \
|
|
||||||
fi; \
|
|
||||||
fi; \
|
fi; \
|
||||||
if [ "$$should_install" = 'yes' ]; then \
|
if test -z "$$disable"; then \
|
||||||
echo "... installing $(COMMAND)"; \
|
echo "... installing $(COMMAND)"; \
|
||||||
head -1 bin/$(COMMAND) > $(TEMPFILE); \
|
head -1 bin/$(COMMAND) > $(TEMPFILE); \
|
||||||
cat $(LIB) >> $(TEMPFILE); \
|
cat $(LIB) >> $(TEMPFILE); \
|
||||||
|
|
@ -82,8 +69,8 @@ install: check
|
||||||
cp -f man/git-*.1 $(DESTDIR)$(MANPREFIX); \
|
cp -f man/git-*.1 $(DESTDIR)$(MANPREFIX); \
|
||||||
echo "cp -f man/git-*.1 $(DESTDIR)$(MANPREFIX)"; \
|
echo "cp -f man/git-*.1 $(DESTDIR)$(MANPREFIX)"; \
|
||||||
fi
|
fi
|
||||||
@mkdir -p $(COMPL_DIR)
|
@mkdir -p $(DESTDIR)$(SYSCONFDIR)/bash_completion.d
|
||||||
cp -f etc/bash_completion.sh $(COMPL_DIR)/git-extras
|
cp -f etc/bash_completion.sh $(DESTDIR)$(SYSCONFDIR)/bash_completion.d/git-extras
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "If you are a zsh user, you may want to 'source $(CODE_DIR)etc/git-extras-completion.zsh'" \
|
@echo "If you are a zsh user, you may want to 'source $(CODE_DIR)etc/git-extras-completion.zsh'" \
|
||||||
"and put this line into ~/.zshrc to enable zsh completion"
|
"and put this line into ~/.zshrc to enable zsh completion"
|
||||||
|
|
@ -132,7 +119,7 @@ uninstall:
|
||||||
echo "... uninstalling $(DESTDIR)$(MANPREFIX)/$(notdir $(MAN))"; \
|
echo "... uninstalling $(DESTDIR)$(MANPREFIX)/$(notdir $(MAN))"; \
|
||||||
rm -f $(DESTDIR)$(MANPREFIX)/$(notdir $(MAN)); \
|
rm -f $(DESTDIR)$(MANPREFIX)/$(notdir $(MAN)); \
|
||||||
)
|
)
|
||||||
rm -f $(COMPL_DIR)/git-extras
|
rm -f $(DESTDIR)$(SYSCONFDIR)/bash_completion.d/git-extras
|
||||||
|
|
||||||
clean: docclean
|
clean: docclean
|
||||||
|
|
||||||
|
|
@ -140,7 +127,4 @@ docclean:
|
||||||
rm -f man/*.1
|
rm -f man/*.1
|
||||||
rm -f man/*.html
|
rm -f man/*.html
|
||||||
|
|
||||||
test:
|
.PHONY: default docs clean docclean check install uninstall
|
||||||
bats ./tests
|
|
||||||
|
|
||||||
.PHONY: default docs check install uninstall clean docclean test
|
|
||||||
|
|
|
||||||
12
Readme.md
12
Readme.md
|
|
@ -6,15 +6,15 @@ Little git extras.
|
||||||
|
|
||||||
Just getting started? Check out these screencasts:
|
Just getting started? Check out these screencasts:
|
||||||
|
|
||||||
* [introduction](https://vimeo.com/45506445) ([archive.org link](https://web.archive.org/web/20230219181235id_/vod-progressive.akamaized.net/exp=1676834145~acl=%2Fvimeo-prod-skyfire-std-us%2F01%2F4101%2F1%2F45506445%2F107111328.mp4~hmac=065b68f23c4b6a222463097b36d1c346995a9559baa9b819972da95550018471/vimeo-prod-skyfire-std-us/01/4101/1/45506445/107111328.mp4)) -- covers `git-ignore`, `git-setup`, `git-changelog`, `git-release`, `git-effort` and more
|
* [introduction](https://vimeo.com/45506445) -- covering git-ignore, git-setup, git-changelog, git-release, git-effort and more
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
See the [Installation](Installation.md) page.
|
See [Installation](Installation.md) page.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
Go to the [Commands](Commands.md) page for basic usage and examples.
|
Go to [Commands](Commands.md) page for basic usage and examples.
|
||||||
|
|
||||||
__GIT utilities__ -- repo summary, repl, changelog population, author commit percentages and more
|
__GIT utilities__ -- repo summary, repl, changelog population, author commit percentages and more
|
||||||
|
|
||||||
|
|
@ -27,8 +27,8 @@ Please read [Contributing](CONTRIBUTING.md) before you make a PR, thanks!
|
||||||
## The change of the default branch
|
## The change of the default branch
|
||||||
|
|
||||||
As of Git Extras 6.4 the assumed default branch name changed from `master` to `main`.
|
As of Git Extras 6.4 the assumed default branch name changed from `master` to `main`.
|
||||||
This affects the Git Extras commands `git archive-file`, `git delete-merged-branches`, `git delta`, `git pull-request`, `git show-merged-branches`, `git show-unmerged-branches`, and `git squash`.
|
This affects the Git Extras commands `git archive-file`, `git delete-merged-branches`, `git delta`, `git pull-request`, `git show-merged-branches`, `git show-unmerged-branches` and `git squash`.
|
||||||
|
|
||||||
To change the default branch name to `master`: change either the configuration `git-extras.default-branch` or `init.defaultBranch` to `master`; the former takes precedence.
|
To change the default branch name to `master`: change either the configuration `git-extras.default-branch` or `init.defaultBranch` to `master`, the former takes precedence.
|
||||||
|
|
||||||
For example, `git config git-extras.default-branch master`.
|
For example, `git config git-extras.default-branch master`
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,17 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# git rev-parse emits an error if not in a git repo so only need to bail out
|
|
||||||
gitdir="$(git rev-parse --git-dir)" || exit
|
gitdir="$(git rev-parse --git-dir)" || exit
|
||||||
|
opfound=
|
||||||
|
fcnt=
|
||||||
|
for i in cherry-pick merge rebase; do
|
||||||
|
f=${i^^}
|
||||||
|
f=${f/-/_}
|
||||||
|
test -f "${gitdir}/${f}_HEAD" && fcnt=1$fcnt && opfound=$i
|
||||||
|
done
|
||||||
|
|
||||||
discover_op() {
|
if [ "${fcnt}" != 1 ]; then
|
||||||
local op
|
echo "I don't know what to abort" >&2
|
||||||
for op in cherry_pick merge rebase revert ; do
|
exit 1
|
||||||
if [ -f "${gitdir}/${op^^}_HEAD" ]; then
|
fi
|
||||||
echo "${op/_/-}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_op() {
|
git "${opfound}" --abort
|
||||||
local op="$1"
|
|
||||||
if [ -z "$op" ]; then
|
|
||||||
echo "No active operation found" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ "$(echo "$op" | wc -l)" -gt 1 ]]; then
|
|
||||||
echo "Multiple active operations found:" >&2
|
|
||||||
for o in $op; do
|
|
||||||
echo " - $o: HEAD: $(cat "${gitdir}/${o}_HEAD")" >&2
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
discover_action() {
|
|
||||||
local action=${1/git-/}
|
|
||||||
if [ "$action" != "abort" ] && [ "$action" != "continue" ]; then
|
|
||||||
echo "Invalid action: $1" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "$action"
|
|
||||||
}
|
|
||||||
|
|
||||||
action=$(discover_action "$(basename "$0")")
|
|
||||||
op=$(discover_op)
|
|
||||||
validate_op "$op"
|
|
||||||
|
|
||||||
git "$op" "--$action"
|
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,16 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
options=""
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<HERE
|
cat <<HERE
|
||||||
usage: git alias [options] # list all aliases
|
usage: git alias # list all aliases
|
||||||
or: git alias [options] <search-pattern> # show aliases matching pattern
|
or: git alias <search-pattern> # show aliases matching pattern
|
||||||
or: git alias [options] <alias-name> <command> # alias a command
|
or: git alias <alias-name> <command> # alias a command
|
||||||
options:
|
|
||||||
|
|
||||||
--global Show or create alias in the system config
|
|
||||||
--local Show or create alias in the repository config
|
|
||||||
HERE
|
HERE
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "$1" == "--local" || "$1" == "--global" ]]; then
|
|
||||||
options=$1
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $# in
|
case $# in
|
||||||
0)
|
0) git config --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort ;;
|
||||||
if [[ -z "$options" ]]; then
|
1) git alias | grep -e "$1" ;;
|
||||||
git config --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort
|
2) git config --global alias."$1" "$2" ;;
|
||||||
else
|
|
||||||
git config "$options" --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
1)
|
|
||||||
if [[ -z "$options" ]]; then
|
|
||||||
git config --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort | grep -e "$1"
|
|
||||||
else
|
|
||||||
git config "$options" --get-regexp 'alias.*' | sed 's/^alias\.//' | sed 's/[ ]/ = /' | sort | grep -e "$1"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
2)
|
|
||||||
if [[ -z "$options" ]]; then
|
|
||||||
git config alias."$1" "$2"
|
|
||||||
else
|
|
||||||
git config "$options" alias."$1" "$2"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*) >&2 echo "error: too many arguments." && usage && exit 1 ;;
|
*) >&2 echo "error: too many arguments." && usage && exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# extract current branch name
|
# extract current branch name
|
||||||
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null)
|
||||||
|
|
||||||
# get name of the most top folder of current directory, used for the
|
# get name of the most top folder of current directory, used for the
|
||||||
# output filename
|
# output filename
|
||||||
ARCHIVE_NAME=$(basename "$(git rev-parse --show-toplevel)")
|
ARCHIVE_NAME=$(basename $(pwd))
|
||||||
|
|
||||||
if [[ $BRANCH = tags* ]]; then
|
if [[ $BRANCH = tags* ]]; then
|
||||||
BRANCH=$(git describe)
|
BRANCH=$(git describe)
|
||||||
echo Building for tag "\"$BRANCH\""
|
echo Building for tag \"$BRANCH\"
|
||||||
FILENAME=$ARCHIVE_NAME.$BRANCH.zip
|
FILENAME=$ARCHIVE_NAME.$BRANCH.zip
|
||||||
else
|
else
|
||||||
echo Building archive on branch "\"$BRANCH\""
|
echo Building archive on branch \"$BRANCH\"
|
||||||
# get a version string, so archives will not be overwritten when creating
|
# get a version string, so archives will not be overwritten when creating
|
||||||
# many of them
|
# many of them
|
||||||
VERSION=$(git describe --always --long)
|
VERSION=$(git describe --always --long)
|
||||||
# if not on master append branch name into the filename
|
# if not on master append branch name into the filename
|
||||||
if [ "$BRANCH" = "$(git_extra_default_branch)" ]; then
|
if [ "$BRANCH" = $(git_extra_default_branch) ]; then
|
||||||
FILENAME=$ARCHIVE_NAME.$VERSION.zip
|
FILENAME=$ARCHIVE_NAME.$VERSION.zip
|
||||||
else
|
else
|
||||||
FILENAME=$ARCHIVE_NAME.$VERSION.$BRANCH.zip
|
FILENAME=$ARCHIVE_NAME.$VERSION.$BRANCH.zip
|
||||||
|
|
@ -28,10 +28,10 @@ fi
|
||||||
FILENAME=${FILENAME//\//-}
|
FILENAME=${FILENAME//\//-}
|
||||||
FILENAME=${FILENAME//\\/-}
|
FILENAME=${FILENAME//\\/-}
|
||||||
# combine path and filename
|
# combine path and filename
|
||||||
OUTPUT=$PWD/$FILENAME
|
OUTPUT=$(pwd)/$FILENAME
|
||||||
|
|
||||||
# building archive
|
# building archive
|
||||||
git archive --format zip --output "$OUTPUT" "$BRANCH"
|
git archive --format zip --output $OUTPUT $BRANCH
|
||||||
|
|
||||||
# also display size of the resulting file
|
# also display size of the resulting file
|
||||||
echo Saved to \""$FILENAME"\" \("$(du -h "$OUTPUT" | cut -f1)"\)
|
echo Saved to \"$FILENAME\" \(`du -h $OUTPUT | cut -f1`\)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
LIST=false
|
LIST=false
|
||||||
NO_EMAIL=false
|
NO_EMAIL=false
|
||||||
FILE=""
|
FILE=""
|
||||||
|
EDITOR=$(git var GIT_EDITOR)
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
|
|
@ -21,9 +22,9 @@ done
|
||||||
|
|
||||||
if ! $LIST; then
|
if ! $LIST; then
|
||||||
FILE=$1
|
FILE=$1
|
||||||
if [ -z "$FILE" ]; then
|
if test "$FILE" = ""; then
|
||||||
FILE=$(find . -mindepth 1 -maxdepth 1 \( -iname '*authors*' -o -iname '*contributors*' \) | head -n1)
|
FILE=$(ls | egrep 'authors|contributors' -i|head -n1)
|
||||||
if [ -z "$FILE" ]; then
|
if test "$FILE" = ""; then
|
||||||
FILE='AUTHORS'
|
FILE='AUTHORS'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -35,11 +36,11 @@ fi
|
||||||
|
|
||||||
authors() {
|
authors() {
|
||||||
if $NO_EMAIL; then
|
if $NO_EMAIL; then
|
||||||
# email will be used to uniq authors.
|
# eamil will be used to uniq authors.
|
||||||
git shortlog HEAD -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++' \
|
git shortlog -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++' \
|
||||||
| awk -F'<' '{gsub(/ +$/, "", $1); print $1}'
|
| awk -F'<' '{gsub(/ +$/, "", $1); print $1}'
|
||||||
else
|
else
|
||||||
git shortlog HEAD -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++'
|
git shortlog -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,5 +51,6 @@ authors() {
|
||||||
if $LIST; then
|
if $LIST; then
|
||||||
authors
|
authors
|
||||||
else
|
else
|
||||||
authors >> "$FILE"
|
authors >> $FILE
|
||||||
|
test -n "$EDITOR" && $EDITOR $FILE
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
116
bin/git-browse
116
bin/git-browse
|
|
@ -1,92 +1,54 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
remote=${1:-""}
|
if [[ $1 == "" ]]
|
||||||
branch=""
|
then
|
||||||
filename=${2:-""}
|
branch=$(git rev-parse --abbrev-ref HEAD 2&> /dev/null)
|
||||||
line1=${3:-""}
|
|
||||||
line2=${4:-""}
|
|
||||||
|
|
||||||
# get remote name
|
|
||||||
if [[ $remote == "" ]]; then
|
|
||||||
branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
|
|
||||||
remote=$(git config branch."${branch}".remote || echo "origin")
|
remote=$(git config branch."${branch}".remote || echo "origin")
|
||||||
|
else
|
||||||
|
remote=$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $remote == "" ]]; then
|
if [[ $remote == "" ]]
|
||||||
|
then
|
||||||
echo "Remote not found"
|
echo "Remote not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
remote_url=$(git remote get-url "$remote") || exit $?
|
remote_url=$(git remote get-url $remote)
|
||||||
|
|
||||||
if [[ $remote_url = git@* ]]; then
|
if [[ $? -ne 0 ]]
|
||||||
url=$(echo "$remote_url" | sed -E -e 's/:/\//' -e 's/\.git$//' -e 's/.*@(.*)/http:\/\/\1/')
|
then
|
||||||
elif [[ $remote_url = http* ]]; then
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $remote_url = git@* ]]
|
||||||
|
then
|
||||||
|
url=$(echo $remote_url | sed -E -e 's/:/\//' -e 's/\.git$//' -e 's/.*@(.*)/http:\/\/\1/')
|
||||||
|
elif [[ $remote_url = http* ]]
|
||||||
|
then
|
||||||
url=${remote_url%.git}
|
url=${remote_url%.git}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# construct urls
|
|
||||||
commit_hash=$(git rev-parse HEAD 2>/dev/null)
|
|
||||||
commit_or_branch=${commit_hash:-${branch}}
|
|
||||||
|
|
||||||
if [[ $remote_url =~ gitlab ]]; then
|
|
||||||
# construct gitlab urls
|
|
||||||
# https://gitlab.com/<user_or_group>/<repo>/-/blob/<commit_or_branch>/<filename>#L<line1>-<line2>
|
|
||||||
if [[ -n ${filename} ]]; then
|
|
||||||
url="${url}/-/blob/${commit_or_branch}/${filename}"
|
|
||||||
if [[ -n "${line1}" ]]; then
|
|
||||||
url="${url}#L${line1}"
|
|
||||||
if [[ -n "${line2}" ]]; then
|
|
||||||
url="${url}-${line2}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [[ $remote_url =~ github ]]; then
|
|
||||||
# construct github urls
|
|
||||||
# https://github.com/<user_or_org>/<repo>/blob/<commit_or_branch>/<filename>#L<line1>-L<line2>
|
|
||||||
if [[ -n "${filename}" ]]; then
|
|
||||||
url="${url}/blob/${commit_or_branch}/${filename}"
|
|
||||||
if [[ -n "${line1}" ]]; then
|
|
||||||
url="${url}#L${line1}"
|
|
||||||
if [[ -n "${line2}" ]]; then
|
|
||||||
url="${url}-L${line2}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [[ $remote_url =~ bitbucket ]]; then
|
|
||||||
# construct bitbucket urls
|
|
||||||
# https://bitbucket.org/<user_or_org>/<repo>/src/<commit_or_branch>/<filename>#lines-<line1>:<line2>
|
|
||||||
if [[ -n ${filename} ]]; then
|
|
||||||
url=${url}/src/${commit_or_branch}/${filename}
|
|
||||||
if [[ -n "${line1}" ]]; then
|
|
||||||
url="${url}#lines-${line1}"
|
|
||||||
if [[ -n "${line2}" ]]; then
|
|
||||||
url="${url}:${line2}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# open url
|
|
||||||
case "$OSTYPE" in
|
case "$OSTYPE" in
|
||||||
darwin*)
|
darwin*)
|
||||||
# MacOS
|
# MacOS
|
||||||
open "$url"
|
open $url
|
||||||
;;
|
;;
|
||||||
msys)
|
msys)
|
||||||
# Git-Bash on Windows
|
# Git-Bash on Windows
|
||||||
start "$url"
|
start $url
|
||||||
;;
|
;;
|
||||||
linux*)
|
linux*)
|
||||||
# Handle WSL on Windows
|
# Handle WSL on Windows
|
||||||
if uname -a | grep -i -q Microsoft && command -v powershell.exe; then
|
if uname -a | grep -i -q Microsoft && command -v powershell.exe
|
||||||
powershell.exe -NoProfile start "$url"
|
then
|
||||||
else
|
powershell.exe -NoProfile start $url
|
||||||
xdg-open "$url"
|
else
|
||||||
fi
|
xdg-open $url
|
||||||
;;
|
fi
|
||||||
*)
|
;;
|
||||||
# fall back to xdg-open for BSDs, etc.
|
*)
|
||||||
xdg-open "$url"
|
# fall back to xdg-open for BSDs, etc.
|
||||||
;;
|
xdg-open $url
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,18 @@ else
|
||||||
remote=$1
|
remote=$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $remote ]]
|
if [[ $remote == "" ]]
|
||||||
then
|
then
|
||||||
echo "Remote not found"
|
echo "Remote not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
remote_url=$(git remote get-url "${remote}") || exit $?
|
remote_url=$(git remote get-url "${remote}")
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]]
|
||||||
|
then
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $remote_url = git@* ]]
|
if [[ $remote_url = git@* ]]
|
||||||
then
|
then
|
||||||
|
|
|
||||||
23
bin/git-brv
23
bin/git-brv
|
|
@ -7,20 +7,6 @@ if ! (( BASH_VERSINFO[0] > 4 ||
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# allow the user to set a default reverse option in an environment variable
|
|
||||||
reverse=$(git config --get git-extras.brv.reverse || echo false)
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case $1 in
|
|
||||||
-r | --reverse)
|
|
||||||
reverse=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -t 1 ]]; then
|
if [[ -t 1 ]]; then
|
||||||
shopt -s checkwinsize
|
shopt -s checkwinsize
|
||||||
COLUMNS=$(tput cols)
|
COLUMNS=$(tput cols)
|
||||||
|
|
@ -50,14 +36,9 @@ for b in "${!upstream[@]}"; do
|
||||||
done
|
done
|
||||||
|
|
||||||
mapfile -t ordered < <(
|
mapfile -t ordered < <(
|
||||||
# the reverse option of git-brv causes the sort to be sorted normally rather than in reverse
|
|
||||||
reverse_opt=""
|
|
||||||
if [[ $reverse = false ]]; then
|
|
||||||
reverse_opt="-r"
|
|
||||||
fi
|
|
||||||
for b in "${!date[@]}"; do
|
for b in "${!date[@]}"; do
|
||||||
printf '%d\t%s\n' "${date[$b]}" "$b"
|
printf '%d\t%s\n' "${date[$b]}" "$b"
|
||||||
done | sort -n $reverse_opt | cut -f2-
|
done | sort -rn | cut -f2-
|
||||||
)
|
)
|
||||||
|
|
||||||
current=$(git symbolic-ref -q --short HEAD)
|
current=$(git symbolic-ref -q --short HEAD)
|
||||||
|
|
@ -78,4 +59,4 @@ for b in "${ordered[@]}"; do
|
||||||
"$color_branch_upstream" "-$uwidth" "${upstream[$b]}" "$reset" \
|
"$color_branch_upstream" "-$uwidth" "${upstream[$b]}" "$reset" \
|
||||||
"$color_diff_commit" "-$hwidth" "${hash[$b]}" "$reset" \
|
"$color_diff_commit" "-$hwidth" "${hash[$b]}" "$reset" \
|
||||||
"$msg"
|
"$msg"
|
||||||
done
|
done
|
||||||
135
bin/git-bulk
135
bin/git-bulk
|
|
@ -9,14 +9,12 @@ guardedmode=false
|
||||||
singlemode=false
|
singlemode=false
|
||||||
allwsmode=false
|
allwsmode=false
|
||||||
quiet=false
|
quiet=false
|
||||||
no_follow_symlinks=false
|
|
||||||
no_follow_hidden=false
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# print usage message
|
# print usage message
|
||||||
#
|
#
|
||||||
usage() {
|
usage() {
|
||||||
echo 1>&2 "usage: git bulk [--no-follow-symlinks] [--no-follow-hidden] [-q|--quiet] [-g] ([-a]|[-w <ws-name>]) <git command>"
|
echo 1>&2 "usage: git bulk [-q|--quiet] [-g] ([-a]|[-w <ws-name>]) <git command>"
|
||||||
echo 1>&2 " git bulk --addworkspace <ws-name> <ws-root-directory> (--from <URL or file>)"
|
echo 1>&2 " git bulk --addworkspace <ws-name> <ws-root-directory> (--from <URL or file>)"
|
||||||
echo 1>&2 " git bulk --removeworkspace <ws-name>"
|
echo 1>&2 " git bulk --removeworkspace <ws-name>"
|
||||||
echo 1>&2 " git bulk --addcurrent <ws-name>"
|
echo 1>&2 " git bulk --addcurrent <ws-name>"
|
||||||
|
|
@ -24,33 +22,22 @@ usage() {
|
||||||
echo 1>&2 " git bulk --listall"
|
echo 1>&2 " git bulk --listall"
|
||||||
}
|
}
|
||||||
|
|
||||||
cdfail() {
|
|
||||||
echo 1>&2 "failed to change directory: $1"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# add another workspace to global git config
|
# add another workspace to global git config
|
||||||
addworkspace() {
|
function addworkspace {
|
||||||
git config --global bulkworkspaces."$wsname" "$wsdir";
|
git config --global bulkworkspaces."$wsname" "$wsdir";
|
||||||
if [ -n "$source" ]; then
|
if [ ! -z "$source" ]; then
|
||||||
if [ ! -d "$wsdir" ]; then echo 1>&2 "Path of workspace doesn't exist, make it first."; exit 1; fi
|
if [ ! -d "$wsdir" ]; then echo 1>&2 "Path of workspace doesn't exist, make it first."; exit 1; fi
|
||||||
regex='http(s)?://|ssh://|(git@)?.*:.*/.*'
|
regex='http(s)?://|ssh://|(git@)?.*:.*/.*'
|
||||||
if [[ "$source" =~ $regex ]]; then
|
if [[ "$source" =~ $regex ]]; then
|
||||||
pushd "$wsdir" > /dev/null || cdfail "$wsdir"
|
pushd "$wsdir" > /dev/null
|
||||||
git clone "$source"
|
git clone "$source"
|
||||||
popd > /dev/null || cdfail "$OLDPWD"
|
popd > /dev/null
|
||||||
else
|
else
|
||||||
source=$(realpath "$source" 2>/dev/null)
|
source=$(realpath "$source" 2>/dev/null)
|
||||||
if [ -f "$source" ]; then
|
if [ -f "$source" ]; then
|
||||||
pushd "$wsdir" > /dev/null || cdfail "$wsdir"
|
pushd "$wsdir" > /dev/null
|
||||||
while IFS= read -r line; do
|
while read -r line; do git clone "$line"; done < "$source";
|
||||||
if [ -n "$line" ]; then
|
popd > /dev/null
|
||||||
# the git clone command to take the complete line in the repository.txt as separate argument. This facilitated the cloning of the repository with a custom folder name.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
git clone $line;
|
|
||||||
fi
|
|
||||||
done < "$source"
|
|
||||||
popd > /dev/null || cdfail "$OLDPWD"
|
|
||||||
else
|
else
|
||||||
echo 1>&2 "format of URL or file unknown"
|
echo 1>&2 "format of URL or file unknown"
|
||||||
fi
|
fi
|
||||||
|
|
@ -59,36 +46,35 @@ addworkspace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# add current directory
|
# add current directory
|
||||||
addcurrent() { git config --global bulkworkspaces."$wsname" "$PWD"; }
|
function addcurrent { git config --global bulkworkspaces."$wsname" "$PWD"; }
|
||||||
|
|
||||||
# remove workspace from global git config
|
# remove workspace from global git config
|
||||||
removeworkspace() { checkWSName && git config --global --unset bulkworkspaces."$wsname"; }
|
function removeworkspace { checkWSName && git config --global --unset bulkworkspaces."$wsname"; }
|
||||||
|
|
||||||
# remove workspace from global git config
|
# remove workspace from global git config
|
||||||
purge() { git config --global --remove-section bulkworkspaces; }
|
function purge { git config --global --remove-section bulkworkspaces; }
|
||||||
|
|
||||||
# list all current workspace locations defined
|
# list all current workspace locations defined
|
||||||
listall() { git config --global --get-regexp bulkworkspaces; }
|
function listall { git config --global --get-regexp bulkworkspaces; }
|
||||||
|
|
||||||
# guarded execution of a git command in one specific repository
|
# guarded execution of a git command in one specific repository
|
||||||
guardedExecution () {
|
function guardedExecution () {
|
||||||
if [ "${quiet?}" != "true" ] || $guardedmode; then
|
|
||||||
echo 1>&2 "${bldred}->${reset} executing ${inverse}git $gitcommand${reset} in repository ${leadingpath%/*}/${bldred}${curdir##*/}${reset}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $guardedmode; then
|
if $guardedmode; then
|
||||||
echo 1>&2 -n " Execute command here (y/n)? "
|
echo 1>&2 -n "${inverse}git $gitcommand${reset} -> execute here (y/n)? "
|
||||||
read -n 1 -r </dev/tty; echo 1>&2
|
read -n 1 -r </dev/tty; echo 1>&2
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
if [[ $REPLY =~ ^[Yy]$ ]]; then atomicExecution "$@"; fi
|
||||||
git "$@"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
git "$@"
|
atomicExecution "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# atomic git command execution with log
|
||||||
|
function atomicExecution () {
|
||||||
|
echo 1>&2 "${bldred}->${reset} executing ${inverse}git $gitcommand${reset}" && git "$@"
|
||||||
|
}
|
||||||
|
|
||||||
# check if the passed command is known as a core git command
|
# check if the passed command is known as a core git command
|
||||||
checkGitCommand () {
|
function checkGitCommand () {
|
||||||
if git help -a | grep -o -q "\b${corecommand}\b"; then
|
if git help -a | grep -o -q "\b${corecommand}\b"; then
|
||||||
echo 1>&2 "Core command \"$corecommand\" accepted."
|
echo 1>&2 "Core command \"$corecommand\" accepted."
|
||||||
else
|
else
|
||||||
|
|
@ -101,83 +87,60 @@ checkGitCommand () {
|
||||||
}
|
}
|
||||||
|
|
||||||
# check if workspace name is registered
|
# check if workspace name is registered
|
||||||
checkWSName () {
|
function checkWSName () {
|
||||||
while read -r workspace; do
|
while read workspace; do
|
||||||
parseWsName "$workspace"
|
parseWsName "$workspace"
|
||||||
if [[ $rwsname == "$wsname" ]]; then return; fi
|
if [[ $rwsname == "$wsname" ]]; then return; fi
|
||||||
done <<< "$(listall)"
|
done <<< "$(echo "$(listall)")"
|
||||||
# when here the ws name was not found
|
# when here the ws name was not found
|
||||||
usage && echo 1>&2 "error: unknown workspace name: $wsname" && exit 1
|
usage && echo 1>&2 "error: unknown workspace name: $wsname" && exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse out wsname from workspacespec
|
# parse out wsname from workspacespec
|
||||||
parseWsName () {
|
function parseWsName () {
|
||||||
local wsspec="$1"
|
local wsspec="$1"
|
||||||
# Get the workspace value from its specification in the `.gitconfig`.
|
|
||||||
# May be an absolute path or a variable name of the form: `$VARNAME`
|
|
||||||
rwsdir=${wsspec#* }
|
rwsdir=${wsspec#* }
|
||||||
if [[ ${rwsdir:0:1} == '$' ]]; then
|
|
||||||
# Dereference the `rwsdir` value which is a variable name.
|
|
||||||
rwsdir_varname=${rwsdir:1}
|
|
||||||
rwsdir=${!rwsdir_varname}
|
|
||||||
if [[ -z "${rwsdir}" ]]; then
|
|
||||||
echo 1>&2 "error: bad environment variable: $rwsdir_varname" && exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
rwsname=${wsspec#*.} && rwsname=${rwsname%% *}
|
rwsname=${wsspec#*.} && rwsname=${rwsname%% *}
|
||||||
}
|
}
|
||||||
|
|
||||||
# detects the wsname of the current directory
|
# detects the wsname of the current directory
|
||||||
wsnameToCurrent () {
|
function wsnameToCurrent () {
|
||||||
while read -r workspace; do
|
while read workspace; do
|
||||||
if [ -z "$workspace" ]; then continue; fi
|
if [ -z "$workspace" ]; then continue; fi
|
||||||
parseWsName "$workspace"
|
parseWsName "$workspace"
|
||||||
if echo "$PWD" | grep -o -q "$rwsdir"; then wsname="$rwsname" && return; fi
|
if echo 1>&2 "$PWD" | grep -o -q "$rwsdir"; then wsname="$rwsname" && return; fi
|
||||||
done <<< "$(listall)"
|
done <<< "$(echo "$(listall)")"
|
||||||
# when here then not in workspace dir
|
# when here then not in workspace dir
|
||||||
echo 1>&2 "error: you are not in a workspace directory. your registered workspaces are:" && \
|
echo 1>&2 "error: you are not in a workspace directory. your registered workspaces are:" && \
|
||||||
wslist="$(listall)" && echo 1>&2 "${wslist:-'<no workspaces defined yet>'}" && exit 1
|
wslist="$(echo "$(listall)")" && echo 1>&2 "${wslist:-'<no workspaces defined yet>'}" && exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# helper to check number of arguments.
|
# helper to check number of arguments.
|
||||||
allowedargcount () {
|
function allowedargcount () {
|
||||||
if [ "$paramcount" -ne "${1:-0}" ] && [ "$paramcount" -ne "${2:-0}" ]; then
|
if [ $paramcount -ne $1 ] && [ $paramcount -ne $2 ]; then
|
||||||
echo 1>&2 "error: wrong number of arguments" && usage;
|
echo 1>&2 "error: wrong number of arguments" && usage;
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# execute the bulk operation
|
# execute the bulk operation
|
||||||
executBulkOp () {
|
function executBulkOp () {
|
||||||
checkGitCommand
|
checkGitCommand
|
||||||
if ! $allwsmode && ! $singlemode; then wsnameToCurrent; fi # by default git bulk works within the 'current' workspace
|
if ! $allwsmode && ! $singlemode; then wsnameToCurrent; fi # by default git bulk works within the 'current' workspace
|
||||||
listall | while read -r workspacespec; do
|
listall | while read workspacespec; do
|
||||||
parseWsName "$workspacespec"
|
parseWsName "$workspacespec"
|
||||||
if [[ -n $wsname ]] && [[ $rwsname != "$wsname" ]]; then continue; fi
|
if [[ -n $wsname ]] && [[ $rwsname != "$wsname" ]]; then continue; fi
|
||||||
cd "$rwsdir" || exit 1
|
eval cd "\"$rwsdir\""
|
||||||
local actual=$PWD
|
local actual=$(pwd)
|
||||||
[ "${quiet?}" != "true" ] && echo 1>&2 "Executing bulk operation in workspace ${inverse}$actual${reset}"
|
[ "${quiet?}" != "false" ] && echo 1>&2 "Executing bulk operation in workspace ${inverse}$actual${reset}"
|
||||||
|
eval find -L . -name ".git" | while read line; do
|
||||||
# build `find` flags depending on command-line options
|
|
||||||
local find_flags=()
|
|
||||||
if [[ "$no_follow_symlinks" == true ]]; then
|
|
||||||
find_flags+=(-P)
|
|
||||||
else
|
|
||||||
find_flags+=(-L)
|
|
||||||
fi
|
|
||||||
# find all git repositories under the workspace on which we want to operate
|
|
||||||
readarray allGitFolders < <(find "${find_flags[@]}" . -name ".git" 2>/dev/null)
|
|
||||||
|
|
||||||
for line in "${allGitFolders[@]}"; do
|
|
||||||
local gitrepodir=${line::${#line}-5} # cut the .git part of find results to have the root git directory of that repository
|
local gitrepodir=${line::${#line}-5} # cut the .git part of find results to have the root git directory of that repository
|
||||||
cd "$gitrepodir" || exit 1 # into git repo location
|
eval cd "\"$gitrepodir\"" # into git repo location
|
||||||
local curdir=$PWD
|
local curdir=$(pwd)
|
||||||
local leadingpath=${curdir#"${actual}"}
|
local leadingpath=${curdir#${actual}}
|
||||||
# do not execute if we do not want to consider a ".git" directory under a hidden directory
|
[ "${quiet?}" != "false" ] && echo 1>&2 "Current repository: ${leadingpath%/*}/${bldred}${curdir##*/}${reset}"
|
||||||
if [ $no_follow_hidden = false ] || ! [[ "$leadingpath" =~ "/." ]]; then
|
guardedExecution "$@"
|
||||||
guardedExecution "$@"
|
eval cd "\"$rwsdir\"" # back to origin location of last find command
|
||||||
fi
|
|
||||||
cd "$rwsdir" || exit 1 # back to origin location of last find command
|
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
@ -194,11 +157,7 @@ while [ "${#}" -ge 1 ] ; do
|
||||||
--listall|--purge)
|
--listall|--purge)
|
||||||
butilcommand="${1:2}" && break ;;
|
butilcommand="${1:2}" && break ;;
|
||||||
--removeworkspace|--addcurrent|--addworkspace)
|
--removeworkspace|--addcurrent|--addworkspace)
|
||||||
butilcommand="${1:2}" && wsname="$2" && wsdir="$3" && if [ "$4" = "--from" ]; then source="$5"; fi && break ;;
|
butilcommand="${1:2}" && wsname="$2" && wsdir="$3" && if [ "$4" == "--from" ]; then source="$5"; fi && break ;;
|
||||||
--no-follow-symlinks)
|
|
||||||
no_follow_symlinks=true ;;
|
|
||||||
--no-follow-hidden)
|
|
||||||
no_follow_hidden=true ;;
|
|
||||||
-a)
|
-a)
|
||||||
allwsmode=true ;;
|
allwsmode=true ;;
|
||||||
-g)
|
-g)
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,6 @@ GIT_MERGELOG_FORMAT="$(git config changelog.mergeformat)"
|
||||||
GIT_EDITOR="$(git var GIT_EDITOR)"
|
GIT_EDITOR="$(git var GIT_EDITOR)"
|
||||||
PROGNAME="git-changelog"
|
PROGNAME="git-changelog"
|
||||||
|
|
||||||
git_editor() {
|
|
||||||
if test -z "${GIT_EDITOR:+set}"
|
|
||||||
then
|
|
||||||
GIT_EDITOR="$(git var GIT_EDITOR)" || return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
eval "$GIT_EDITOR" '"$@"'
|
|
||||||
}
|
|
||||||
|
|
||||||
_usage() {
|
_usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
usage: $PROGNAME options [file]
|
usage: $PROGNAME options [file]
|
||||||
|
|
@ -155,8 +146,6 @@ _fetchCommitRange() {
|
||||||
local start_tag="$2"
|
local start_tag="$2"
|
||||||
local final_tag="$3"
|
local final_tag="$3"
|
||||||
|
|
||||||
# This shellcheck disable is applied to the whole if-body
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
if [[ "$list_all" == true ]]; then
|
if [[ "$list_all" == true ]]; then
|
||||||
git log $GIT_LOG_OPTS --pretty=format:"${CUR_GIT_LOG_FORMAT}"
|
git log $GIT_LOG_OPTS --pretty=format:"${CUR_GIT_LOG_FORMAT}"
|
||||||
elif [[ -n "$final_tag" && "$start_tag" == "null" ]]; then
|
elif [[ -n "$final_tag" && "$start_tag" == "null" ]]; then
|
||||||
|
|
@ -244,7 +233,7 @@ commitList() {
|
||||||
# fetch our tags
|
# fetch our tags
|
||||||
local _ref _date _tag _tab='%x09'
|
local _ref _date _tag _tab='%x09'
|
||||||
local _tag_regex='tag: *'
|
local _tag_regex='tag: *'
|
||||||
while IFS=$'\t' read -r _ref _date _tag; do
|
while IFS=$'\t' read _ref _date _tag; do
|
||||||
[[ -z "${_tag}" ]] && continue
|
[[ -z "${_tag}" ]] && continue
|
||||||
# strip out tags form ()
|
# strip out tags form ()
|
||||||
# git v2.2.0+ supports '%D', like '%d' without the " (", ")" wrapping. One day we should use it instead.
|
# git v2.2.0+ supports '%D', like '%d' without the " (", ")" wrapping. One day we should use it instead.
|
||||||
|
|
@ -291,8 +280,7 @@ commitList() {
|
||||||
for (( i=0; i<"${_tags_list_keys_length}"; i++ )); do
|
for (( i=0; i<"${_tags_list_keys_length}"; i++ )); do
|
||||||
local __curr_tag="${tags_list_keys[$i]}"
|
local __curr_tag="${tags_list_keys[$i]}"
|
||||||
local __prev_tag="${tags_list_keys[$i+1]:-null}"
|
local __prev_tag="${tags_list_keys[$i+1]:-null}"
|
||||||
local __curr_date
|
local __curr_date="$(_valueForKeyFakeAssocArray "${__curr_tag}" "${tags_list[*]}")"
|
||||||
__curr_date="$(_valueForKeyFakeAssocArray "${__curr_tag}" "${tags_list[*]}")"
|
|
||||||
__curr_date="${__curr_date##*=>}"
|
__curr_date="${__curr_date##*=>}"
|
||||||
|
|
||||||
# output latest commits, up until the most-recent tag, these are all
|
# output latest commits, up until the most-recent tag, these are all
|
||||||
|
|
@ -388,7 +376,7 @@ _exit() {
|
||||||
# so we need to calculate the total column number(COL_NUM) of header first.
|
# so we need to calculate the total column number(COL_NUM) of header first.
|
||||||
# Why don't we just use the last column?
|
# Why don't we just use the last column?
|
||||||
# Because the body of CMD column may contain space and be treated as multiple fields.
|
# Because the body of CMD column may contain space and be treated as multiple fields.
|
||||||
pid_list=( $(ps -f |
|
pid_list=( $(ps -f |
|
||||||
awk -v ppid=$$ 'NR == 1 {
|
awk -v ppid=$$ 'NR == 1 {
|
||||||
COL_NUM = NF
|
COL_NUM = NF
|
||||||
}
|
}
|
||||||
|
|
@ -403,7 +391,7 @@ _exit() {
|
||||||
local _pid
|
local _pid
|
||||||
for _pid in "${pid_list[@]}"; do
|
for _pid in "${pid_list[@]}"; do
|
||||||
echo "killing: ${_pid}"
|
echo "killing: ${_pid}"
|
||||||
kill -TERM "${_pid}"
|
kill -TERM ${_pid}
|
||||||
done
|
done
|
||||||
|
|
||||||
wait; stty sane; exit 1
|
wait; stty sane; exit 1
|
||||||
|
|
@ -486,10 +474,10 @@ main() {
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
# The default log format unless already set
|
# The default log format unless already set
|
||||||
[[ -z "$CUR_GIT_LOG_FORMAT" ]] && CUR_GIT_LOG_FORMAT="$GIT_LOG_FORMAT"
|
[[ -z "$CUR_GIT_LOG_FORMAT" ]] && CUR_GIT_LOG_FORMAT="$GIT_LOG_FORMAT"
|
||||||
|
|
||||||
local _tag="$(_valueForKeyFakeAssocArray "start_tag" "${option[*]}")"
|
local _tag="$(_valueForKeyFakeAssocArray "start_tag" "${option[*]}")"
|
||||||
local start_commit="$(_valueForKeyFakeAssocArray "start_commit" "${option[*]}")"
|
local start_commit="$(_valueForKeyFakeAssocArray "start_commit" "${option[*]}")"
|
||||||
|
|
||||||
|
|
@ -499,6 +487,7 @@ main() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
start_commit="$start_commit"
|
||||||
start_tag="$(git describe --tags --contains "$start_commit" 2>/dev/null || echo 'null')"
|
start_tag="$(git describe --tags --contains "$start_commit" 2>/dev/null || echo 'null')"
|
||||||
if [[ -z "$start_tag" ]]; then
|
if [[ -z "$start_tag" ]]; then
|
||||||
_error "Could find the associative tag for the start-commit!"
|
_error "Could find the associative tag for the start-commit!"
|
||||||
|
|
@ -540,10 +529,9 @@ main() {
|
||||||
#
|
#
|
||||||
# generate changelog
|
# generate changelog
|
||||||
#
|
#
|
||||||
local tmpfile changelog title_tag
|
local tmpfile="$(git_extra_mktemp)"
|
||||||
tmpfile="$(git_extra_mktemp)"
|
local changelog="$(_valueForKeyFakeAssocArray "output_file" "${option[*]}")"
|
||||||
changelog="$(_valueForKeyFakeAssocArray "output_file" "${option[*]}")"
|
local title_tag="$(_valueForKeyFakeAssocArray "title_tag" "${option[*]}")"
|
||||||
title_tag="$(_valueForKeyFakeAssocArray "title_tag" "${option[*]}")"
|
|
||||||
|
|
||||||
if [[ "$(_valueForKeyFakeAssocArray "list_style" "${option[*]}")" == true ]]; then
|
if [[ "$(_valueForKeyFakeAssocArray "list_style" "${option[*]}")" == true ]]; then
|
||||||
if [[ "$(_valueForKeyFakeAssocArray "list_all" "${option[*]}")" == true ]]; then
|
if [[ "$(_valueForKeyFakeAssocArray "list_all" "${option[*]}")" == true ]]; then
|
||||||
|
|
@ -562,7 +550,7 @@ main() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "$changelog" ]]; then
|
if [[ -z "$changelog" ]]; then
|
||||||
changelog="$(find . -mindepth 1 -maxdepth 1 \( -iname '*change*' -o -iname '*history*' \) | head -n1)"
|
changelog="$(ls | egrep 'change|history' -i | head -n1)"
|
||||||
if [[ -z "$changelog" ]]; then
|
if [[ -z "$changelog" ]]; then
|
||||||
changelog="History.md";
|
changelog="History.md";
|
||||||
fi
|
fi
|
||||||
|
|
@ -581,11 +569,12 @@ main() {
|
||||||
else
|
else
|
||||||
cp -f "$tmpfile" "$changelog"
|
cp -f "$tmpfile" "$changelog"
|
||||||
rm -f "$tmpfile"
|
rm -f "$tmpfile"
|
||||||
|
# Use `eval` to handle GIT_EDITOR which contains space and options,
|
||||||
if [[ -n "$GIT_EDITOR" ]]; then
|
# like ""C:\Program Files (x86)\Notepad++\notepad++.exe" -multiInst ".
|
||||||
git_editor "$changelog" || _exit
|
# Thanks @JanSchulz to inspire me this solution
|
||||||
else
|
[[ -n "$GIT_EDITOR" ]] && eval $GIT_EDITOR "$changelog"
|
||||||
less "$changelog" || _exit
|
if [[ $? -ne 0 ]]; then
|
||||||
|
_exit
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
PROGNAME="git-clear"
|
PROGNAME="git-clear"
|
||||||
FORCE=0
|
FORCE=0
|
||||||
|
|
||||||
_usage() {
|
function _usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
usage: $PROGNAME options
|
usage: $PROGNAME options
|
||||||
usage: $PROGNAME -h|help|?
|
usage: $PROGNAME -h|help|?
|
||||||
|
|
@ -32,12 +32,12 @@ done
|
||||||
|
|
||||||
# Only wait for answer if not forced by user
|
# Only wait for answer if not forced by user
|
||||||
if [[ $FORCE == 0 ]]; then
|
if [[ $FORCE == 0 ]]; then
|
||||||
echo -n "Sure? - THIS COMMAND MAY DELETE FILES THAT CANNOT BE RECOVERED, including those in .gitignore [y/N]: "
|
echo -n "Sure? - This command may delete files that cannot be recovered, including those in .gitignore [y/N]: "
|
||||||
read -r clean
|
read clean
|
||||||
else
|
else
|
||||||
clean=y
|
clean=y
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$clean" = "y" ]; then
|
if [ "$clean" == "y" ]; then
|
||||||
git clean -d -f -x && git reset --hard
|
git clean -d -f -x && git reset --hard
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
echo -n "Sure? - This command may delete files that cannot be recovered. Files and directories in .gitignore will be preserved [y/N]: "
|
echo -n "Sure? - This command may delete files that cannot be recovered. Files and directories in .gitignore will be preserved [y/N]: "
|
||||||
read -r answer
|
read ans
|
||||||
if [ "$answer" = "y" ]
|
if [ "$ans" == "y" ]
|
||||||
then git clean -d -f && git reset --hard
|
then git clean -d -f && git reset --hard
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
REF=""
|
SINCE="last week"
|
||||||
SINCE=""
|
test $# -ne 0 && SINCE=$@
|
||||||
|
echo "... commits since $SINCE" >&2
|
||||||
while [[ $# -gt 0 ]]; do
|
git log --pretty='%an - %s' --after="@{$SINCE}"
|
||||||
case "$1" in
|
|
||||||
-r|--ref)
|
|
||||||
if [[ -z "$2" ]]; then
|
|
||||||
echo "error: option $1 requires an argument" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
REF="$2"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# non-flag args accumulation, e.g. "last " + "week" -> "last week"
|
|
||||||
SINCE="${SINCE:+$SINCE }$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -n "$REF" && -n "$SINCE" ]]; then
|
|
||||||
echo "error: '--ref <ref>' and '<date>' are mutually exclusive" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SINCE="${SINCE:-last week}"
|
|
||||||
|
|
||||||
if [[ -n "$REF" ]]; then
|
|
||||||
git log --pretty='%h %an - %s' "$REF..HEAD"
|
|
||||||
else
|
|
||||||
git log --pretty='%h %an - %s' --after="@{$SINCE}"
|
|
||||||
fi
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
git-abort
|
|
||||||
|
|
@ -5,4 +5,4 @@ if test "$1" = "--all"; then
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo total "$(git rev-list --count HEAD)"
|
echo total `git rev-list --count HEAD`
|
||||||
|
|
|
||||||
46
bin/git-cp
46
bin/git-cp
|
|
@ -32,47 +32,9 @@ elif [[ "$CURRENT_FILENAME" == "" ]]; then
|
||||||
usage
|
usage
|
||||||
exit 10 # Missing arguments CURRENT_FILENAME
|
exit 10 # Missing arguments CURRENT_FILENAME
|
||||||
else
|
else
|
||||||
if [ -e "$DESTINATION_FILENAME" ]; then
|
echo "Coping $CURRENT_FILENAME into $DESTINATION_FILENAME"
|
||||||
echo 1>&2 "$DESTINATION_FILENAME already exists."
|
cp -r "${CURRENT_FILENAME}" "${DESTINATION_FILENAME}"
|
||||||
echo 1>&2 "Make sure to remove the destination first."
|
|
||||||
exit 40
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$DESTINATION_FILENAME" == */ ]]; then
|
git add "$DESTINATION_FILENAME"
|
||||||
echo 1>&2 "$DESTINATION_FILENAME is not a file path."
|
git commit -m "Duplicate ${CURRENT_FILENAME} history in ${DESTINATION_FILENAME} history." -n
|
||||||
exit 80
|
|
||||||
fi
|
|
||||||
if [[ "$DESTINATION_FILENAME" == */* ]]; then
|
|
||||||
DESTINATION_DIR="${DESTINATION_FILENAME%/*}"
|
|
||||||
if ! mkdir -p "$DESTINATION_DIR"; then
|
|
||||||
echo 1>&2 "Failed to create destination directory: $DESTINATION_DIR"
|
|
||||||
exit 160
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
echo "Copying $CURRENT_FILENAME into $DESTINATION_FILENAME"
|
|
||||||
|
|
||||||
# Pre-check that the source and destination will work
|
|
||||||
git mv --dry-run "${CURRENT_FILENAME}" "${DESTINATION_FILENAME}"
|
|
||||||
|
|
||||||
# Make a new branch and switch to it
|
|
||||||
BRANCH_NAME="git-cp-$(date +%s)"
|
|
||||||
git checkout -b "$BRANCH_NAME"
|
|
||||||
|
|
||||||
# Move the original file to the new destination, in this branch
|
|
||||||
git mv "${CURRENT_FILENAME}" "${DESTINATION_FILENAME}"
|
|
||||||
git commit -nm "--Duplicate $CURRENT_FILENAME history into $DESTINATION_FILENAME"
|
|
||||||
|
|
||||||
# Restore the original file to keep it in the history
|
|
||||||
git checkout HEAD~ "${CURRENT_FILENAME}"
|
|
||||||
git commit -nm "--Restore $CURRENT_FILENAME"
|
|
||||||
|
|
||||||
# Switch to the original branch and merge this back in.
|
|
||||||
git checkout -
|
|
||||||
git merge --no-ff "$BRANCH_NAME" -m "Copy $CURRENT_FILENAME into $DESTINATION_FILENAME"
|
|
||||||
|
|
||||||
# We're now done with the branch, so delete it.
|
|
||||||
# We shouldn't need -D here, as we've already merged it back in.
|
|
||||||
git branch -d "$BRANCH_NAME"
|
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
test $# -eq 0 && echo "branch argument required." 1>&2 && exit 1
|
test $# -eq 0 && echo "branch argument required." 1>&2 && exit 1
|
||||||
|
|
||||||
# preference takes lowest priority; look for remote from prefs first
|
# preference takes lowest priority; look for remote from prefs first
|
||||||
REMOTE_PREF=$(git config git-extras.create-branch.remote)
|
REMOTE_PREF=`git config git-extras.create-branch.remote`
|
||||||
if [ -n "$REMOTE_PREF" ]; then
|
if [ -n "$REMOTE_PREF" ]; then
|
||||||
REMOTE=$REMOTE_PREF
|
REMOTE=$REMOTE_PREF
|
||||||
fi
|
fi
|
||||||
|
|
@ -39,25 +39,25 @@ then
|
||||||
REMOTE=origin
|
REMOTE=origin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
test -z "$BRANCH" && echo "branch argument required." 1>&2 && exit 1
|
test -z $BRANCH && echo "branch argument required." 1>&2 && exit 1
|
||||||
|
|
||||||
if [[ -n $REMOTE ]]
|
if [[ -n $REMOTE ]]
|
||||||
then
|
then
|
||||||
stderr=$(git_extra_mktemp)
|
stderr=$(git_extra_mktemp)
|
||||||
git ls-remote --exit-code "$REMOTE" 1>/dev/null 2>"$stderr"
|
git ls-remote --exit-code $REMOTE 1>/dev/null 2>"$stderr"
|
||||||
REMOTE_EXIT=$?
|
REMOTE_EXIT=$?
|
||||||
REMOTE_ERROR=$(<"$stderr")
|
REMOTE_ERROR=$(<"$stderr")
|
||||||
rm -f "$stderr"
|
rm -f "$stderr"
|
||||||
if [ $REMOTE_EXIT -eq 0 ]
|
if [ $REMOTE_EXIT -eq 0 ]
|
||||||
then
|
then
|
||||||
if [[ -n $START_POINT ]]; then
|
if [[ -n $START_POINT ]]; then
|
||||||
git fetch "$REMOTE"
|
git fetch $REMOTE
|
||||||
git checkout --track -b "$BRANCH" "$START_POINT"
|
git checkout --track -b $BRANCH $START_POINT
|
||||||
git push "$REMOTE" "HEAD:refs/heads/$BRANCH"
|
git push $REMOTE HEAD:refs/heads/$BRANCH
|
||||||
else
|
else
|
||||||
git push "$REMOTE" "HEAD:refs/heads/$BRANCH"
|
git push $REMOTE HEAD:refs/heads/$BRANCH
|
||||||
git fetch "$REMOTE"
|
git fetch $REMOTE
|
||||||
git checkout --track -b "$BRANCH" "$REMOTE/$BRANCH"
|
git checkout --track -b $BRANCH $REMOTE/$BRANCH
|
||||||
fi
|
fi
|
||||||
exit $?
|
exit $?
|
||||||
else
|
else
|
||||||
|
|
@ -70,7 +70,7 @@ fi
|
||||||
|
|
||||||
if [[ -n $START_POINT ]]
|
if [[ -n $START_POINT ]]
|
||||||
then
|
then
|
||||||
git checkout -b "$BRANCH" "$START_POINT"
|
git checkout -b $BRANCH $START_POINT
|
||||||
else
|
else
|
||||||
git checkout -b "$BRANCH"
|
git checkout -b $BRANCH
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Assert there is at least one branch provided
|
# Assert there is at least one branch provided
|
||||||
test -z "$1" && echo "branch required." 1>&2 && exit 1
|
test -z $1 && echo "branch required." 1>&2 && exit 1
|
||||||
|
|
||||||
for branch in "$@"
|
for branch in "$@"
|
||||||
do
|
do
|
||||||
remote=$(git config "branch.$branch.remote" || echo "origin")
|
remote=$(git config branch.$branch.remote || echo "origin")
|
||||||
ref=$(git config "branch.$branch.merge" || echo "refs/heads/$branch")
|
ref=$(git config branch.$branch.merge || echo "refs/heads/$branch")
|
||||||
|
|
||||||
git branch -D "$branch" || true
|
git branch -D $branch || true
|
||||||
# Avoid deleting local upstream
|
# Avoid deleting local upstream
|
||||||
[ "$remote" = "." ] && continue
|
[ "$remote" == "." ] && continue
|
||||||
git branch -d -r "$remote/$branch" || continue
|
git branch -d -r $remote/$branch || continue
|
||||||
git push "$remote" ":$ref"
|
git push $remote :$ref
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
dry_run=false
|
|
||||||
force=false
|
|
||||||
prune=false
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
-n|--dry-run)
|
|
||||||
dry_run=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-f|--force)
|
|
||||||
force=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-p|--prune)
|
|
||||||
prune=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown option: $1"
|
|
||||||
echo "Usage: git delete-gone-branches [-n|--dry-run] [-f|--force] [-p|--prune]"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$prune" = true ]; then
|
|
||||||
git fetch --prune
|
|
||||||
fi
|
|
||||||
|
|
||||||
gone_branches=$(git for-each-ref --format \
|
|
||||||
'%(if:equals=gone)%(upstream:track,nobracket)%(then)%(refname:short)%(end)' refs/heads/ | sed '/^$/d')
|
|
||||||
|
|
||||||
if [ -z "$gone_branches" ]; then
|
|
||||||
echo "No branches with a gone remote found."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$dry_run" = true ]; then
|
|
||||||
echo "Would delete the following branches:"
|
|
||||||
echo "$gone_branches"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "The following branches will be deleted:"
|
|
||||||
echo "$gone_branches"
|
|
||||||
|
|
||||||
if [ "$force" = false ]; then
|
|
||||||
read -r -p "Delete these branches? [y/N] " confirm
|
|
||||||
if [[ ! "$confirm" =~ ^[yY]$ ]]; then
|
|
||||||
echo "Aborted."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$gone_branches" | xargs git branch -D
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
branches=$(git branch --no-color --merged | grep -vE "^(\*|\+)" | grep -v "$(git_extra_default_branch)" | grep -v svn)
|
branches=$(git branch --no-color --merged | grep -vE "^(\*|\+)" | grep -v $(git_extra_default_branch) | grep -v svn)
|
||||||
if [ -n "$branches" ]
|
if [ -n "$branches" ]
|
||||||
then
|
then
|
||||||
echo "$branches" | xargs git branch -d
|
echo "$branches" | xargs -n 1 git branch -d
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,17 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
proceed=false
|
|
||||||
if [[ $# -gt 0 && ("$1" == "--proceed" || "$1" == "-p") ]]; then
|
|
||||||
proceed=true
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
targetBranch=$(git rev-parse --abbrev-ref HEAD)
|
targetBranch=$(git rev-parse --abbrev-ref HEAD)
|
||||||
else
|
else
|
||||||
targetBranch=$1
|
targetBranch=$1
|
||||||
git checkout "$targetBranch"
|
git checkout $targetBranch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git for-each-ref refs/heads/ "--format=%(refname:short)" | while read -r branch; do
|
git for-each-ref refs/heads/ "--format=%(refname:short)" | while read branch; do
|
||||||
mergeBase=$(git merge-base "$targetBranch" "$branch")
|
mergeBase=$(git merge-base $targetBranch $branch)
|
||||||
|
|
||||||
if [[ $(git cherry "$targetBranch" "$(git commit-tree "$(git rev-parse "$branch^{tree}")" -p "$mergeBase" -m _)") == "-"* ]]; then
|
if [[ $(git cherry $targetBranch $(git commit-tree $(git rev-parse $branch\^{tree}) -p $mergeBase -m _)) == "-"* ]]; then
|
||||||
if [[ $proceed == true ]]; then
|
git branch -D $branch
|
||||||
git branch -D "$branch" || true
|
|
||||||
else
|
|
||||||
git branch -D "$branch"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ test ! -f '.gitmodules' && abort 2 '.gitmodules file not found'
|
||||||
|
|
||||||
NAME="${1%/}"
|
NAME="${1%/}"
|
||||||
test -z "$(git config --file='.gitmodules' "submodule.$NAME.url")" \
|
test -z "$(git config --file='.gitmodules' "submodule.$NAME.url")" \
|
||||||
&& abort 3 'Submodule not found'
|
&& abort 3 'Submodule not found'
|
||||||
|
|
||||||
# 1. Handle the .git directory
|
# 1. Handle the .git directory
|
||||||
# 1.a. Delete the relevant section from .git/config
|
# 1.a. Delete the relevant section from .git/config
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Assert there is at least one tag provided
|
# Assert there is at least one tag provided
|
||||||
test -z "$1" && echo "tag required." 1>&2 && exit 1
|
test -z $1 && echo "tag required." 1>&2 && exit 1
|
||||||
|
|
||||||
# Detect the default remote exists or not
|
# Detect the default remote exists or not
|
||||||
default_remote=$(git config git-extras.default-remote)
|
default_remote=$(git config git-extras.default-remote)
|
||||||
|
|
@ -22,7 +22,5 @@ do
|
||||||
done
|
done
|
||||||
|
|
||||||
# Delete all the tags
|
# Delete all the tags
|
||||||
# shellcheck disable=SC2086
|
|
||||||
git tag -d $local_tags
|
git tag -d $local_tags
|
||||||
# shellcheck disable=SC2086
|
git push $origin $origin_refs
|
||||||
git push "$origin" $origin_refs
|
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,4 @@ else
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git diff --name-only --diff-filter="$filter" "$branch"
|
git diff --name-only --diff-filter=$filter $branch
|
||||||
|
|
@ -59,14 +59,14 @@ active_days() {
|
||||||
|
|
||||||
color_for() {
|
color_for() {
|
||||||
if [ "$to_tty" = true ]; then
|
if [ "$to_tty" = true ]; then
|
||||||
if [ "$1" -gt 200 ]; then color="$(tputq setaf 1)$(tputq bold)"
|
if [ $1 -gt 200 ]; then color="$(tputq setaf 1)$(tputq bold)"
|
||||||
elif [ "$1" -gt 150 ]; then color="$(tputq setaf 1)" # red
|
elif [ $1 -gt 150 ]; then color="$(tputq setaf 1)" # red
|
||||||
elif [ "$1" -gt 125 ]; then color="$(tputq setaf 2)$(tputq bold)"
|
elif [ $1 -gt 125 ]; then color="$(tputq setaf 2)$(tputq bold)"
|
||||||
elif [ "$1" -gt 100 ]; then color="$(tputq setaf 2)" # green
|
elif [ $1 -gt 100 ]; then color="$(tputq setaf 2)" # green
|
||||||
elif [ "$1" -gt 75 ]; then color="$(tputq setaf 5)$(tputq bold)"
|
elif [ $1 -gt 75 ]; then color="$(tputq setaf 5)$(tputq bold)"
|
||||||
elif [ "$1" -gt 50 ]; then color="$(tputq setaf 5)" # purplish
|
elif [ $1 -gt 50 ]; then color="$(tputq setaf 5)" # purplish
|
||||||
elif [ "$1" -gt 25 ]; then color="$(tputq setaf 3)$(tputq bold)"
|
elif [ $1 -gt 25 ]; then color="$(tputq setaf 3)$(tputq bold)"
|
||||||
elif [ "$1" -gt 10 ]; then color="$(tputq setaf 3)" # yellow
|
elif [ $1 -gt 10 ]; then color="$(tputq setaf 3)" # yellow
|
||||||
else color="$(tputq sgr0)" # default color
|
else color="$(tputq sgr0)" # default color
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|
@ -84,38 +84,37 @@ effort() {
|
||||||
local color reset_color commits len dot f_dot i msg active
|
local color reset_color commits len dot f_dot i msg active
|
||||||
reset_color=""
|
reset_color=""
|
||||||
test "$to_tty" = true && reset_color="$(tputq sgr0)"
|
test "$to_tty" = true && reset_color="$(tputq sgr0)"
|
||||||
if ! commit_dates=$(dates "$path"); then
|
commit_dates=`dates "$path"`
|
||||||
exit 255
|
[ $? -gt 0 ] && exit 255
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure it's not just an empty line
|
# Ensure it's not just an empty line
|
||||||
if [ -z "$(head -c 1 <<<"$commit_dates")" ]
|
if [ -z "`head -c 1 <<<$(echo $commit_dates)`" ]
|
||||||
then
|
then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
commits=$(wc -l <<<"$commit_dates")
|
commits=`wc -l <<<"$(echo "$commit_dates")"`
|
||||||
color='90'
|
color='90'
|
||||||
|
|
||||||
# ignore <= --above
|
# ignore <= --above
|
||||||
test "$commits" -le "$above" && exit 0
|
test $commits -le $above && exit 0
|
||||||
|
|
||||||
# commits
|
# commits
|
||||||
color_for $(( commits - above ))
|
color_for $(( $commits - $above ))
|
||||||
len=${#path}
|
len=${#path}
|
||||||
dot="."
|
dot="."
|
||||||
f_dot="$path"
|
f_dot="$path"
|
||||||
i=0 ; while test $i -lt $(( columns - len )) ; do
|
i=0 ; while test $i -lt $(( $columns - $len )) ; do
|
||||||
f_dot=$f_dot$dot
|
f_dot=$f_dot$dot
|
||||||
i=$((i+1))
|
i=$(($i+1))
|
||||||
done
|
done
|
||||||
|
|
||||||
msg=$(printf " ${color}%s %-10d" "$f_dot" "$commits")
|
msg=$(printf " ${color}%s %-10d" "$f_dot" $commits)
|
||||||
|
|
||||||
# active days
|
# active days
|
||||||
active=$(active_days "$commit_dates")
|
active=`active_days "$commit_dates"`
|
||||||
color_for $(( active - above ))
|
color_for $(( $active - $above ))
|
||||||
msg="$msg $(printf "${color} %d${reset_color}\n" "$active")"
|
msg="$msg $(printf "${color} %d${reset_color}\n" $active)"
|
||||||
echo "$msg"
|
echo "$msg"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,16 +136,7 @@ sort_effort() {
|
||||||
clear
|
clear
|
||||||
echo " "
|
echo " "
|
||||||
heading
|
heading
|
||||||
< "$tmp" sort -rn -k 2
|
< $tmp sort -rn -k 2
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# get processor count, default 8
|
|
||||||
#
|
|
||||||
procs() {
|
|
||||||
if ! (nproc --all || getconf NPROCESSORS_ONLN || getconf _NPROCESSORS_ONLN || grep -c processor /proc/cpuinfo) 2>/dev/null; then
|
|
||||||
echo 8
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare -a paths=()
|
declare -a paths=()
|
||||||
|
|
@ -191,8 +181,8 @@ export args_to_git_log
|
||||||
|
|
||||||
if test "${#paths}" -eq 0; then
|
if test "${#paths}" -eq 0; then
|
||||||
save_ifs=$IFS
|
save_ifs=$IFS
|
||||||
IFS=$(echo -en "\n\b")
|
IFS=`echo -en "\n\b"`
|
||||||
paths=($(git ls-files))
|
paths=(`git ls-files`)
|
||||||
IFS=$save_ifs
|
IFS=$save_ifs
|
||||||
unset save_ifs
|
unset save_ifs
|
||||||
fi
|
fi
|
||||||
|
|
@ -217,18 +207,14 @@ heading
|
||||||
|
|
||||||
# send paths to effort
|
# send paths to effort
|
||||||
nPaths=${#paths[@]}
|
nPaths=${#paths[@]}
|
||||||
nProcs=$(procs)
|
|
||||||
nJobs="\j"
|
|
||||||
for ((i=0; i<nPaths; ++i))
|
for ((i=0; i<nPaths; ++i))
|
||||||
do
|
do
|
||||||
while (( ${nJobs@P} >= nProcs )); do
|
|
||||||
wait -n
|
|
||||||
done
|
|
||||||
effort "${paths[i]}" &
|
effort "${paths[i]}" &
|
||||||
done|tee "$tmp"
|
done|tee $tmp
|
||||||
|
wait
|
||||||
|
|
||||||
# if more than one path, sort and print
|
# if more than one path, sort and print
|
||||||
test "$(wc -l "$tmp" | awk '{print $1}')" -gt 1 && sort_effort
|
test "$(wc -l $tmp | awk '{print $1}')" -gt 1 && sort_effort
|
||||||
echo
|
echo
|
||||||
|
|
||||||
show_cursor_and_cleanup
|
show_cursor_and_cleanup
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
VERSION="7.6.0-dev"
|
VERSION="6.4.0"
|
||||||
INSTALL_SCRIPT="https://raw.githubusercontent.com/tj/git-extras/main/install.sh"
|
INSTALL_SCRIPT="https://raw.githubusercontent.com/tj/git-extras/master/install.sh"
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
local bin="$(command -v git-extras)"
|
local bin="$(which git-extras)"
|
||||||
local prefix=${bin%/*/*}
|
local prefix=${bin%/*/*}
|
||||||
local orig=$PWD
|
local orig=$PWD
|
||||||
|
|
||||||
|
|
@ -14,10 +14,10 @@ update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateForWindows() {
|
updateForWindows() {
|
||||||
local bin="$(command -v git-extras)"
|
local bin="$(which git-extras)"
|
||||||
local prefix=${bin%/*/*}
|
local prefix=${bin%/*/*}
|
||||||
local orig=$PWD
|
local orig=$PWD
|
||||||
|
|
||||||
# we need to clean up /tmp manually on windows
|
# we need to clean up /tmp manually on windows
|
||||||
cd /tmp \
|
cd /tmp \
|
||||||
&& rm -rf ./git-extras \
|
&& rm -rf ./git-extras \
|
||||||
|
|
|
||||||
|
|
@ -6,30 +6,22 @@ if [ -z "$branch_prefix" ]; then
|
||||||
branch_prefix="feature"
|
branch_prefix="feature"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
branch_separator=$(git config --get git-extras.feature.separator)
|
|
||||||
|
|
||||||
if [ -z "$branch_separator" ]; then
|
|
||||||
branch_separator="/"
|
|
||||||
fi
|
|
||||||
|
|
||||||
merge_mode="--no-ff"
|
merge_mode="--no-ff"
|
||||||
finish=false
|
|
||||||
declare -a argv
|
declare -a argv
|
||||||
while test $# != 0
|
while test $# != 0
|
||||||
do
|
do
|
||||||
case $1 in
|
case $1 in
|
||||||
-a|--alias )
|
-a|--alias )
|
||||||
if [[ -n $2 ]] && [[ $2 != -- ]]
|
if [[ -n $2 ]]
|
||||||
then
|
then
|
||||||
shift # shift -a|-alias
|
shift # shift -a|-alias
|
||||||
branch_prefix=$1
|
branch_prefix=$1
|
||||||
else
|
else
|
||||||
echo >&2 "option $1 requires a value"
|
argv+=($1) # treat tail '-a' as <name>
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
-r|--remote )
|
-r|--remote )
|
||||||
if [[ -n $2 ]] && [[ $2 != -- ]]
|
if [[ -n $2 ]]
|
||||||
then
|
then
|
||||||
remote=$2
|
remote=$2
|
||||||
shift
|
shift
|
||||||
|
|
@ -37,16 +29,6 @@ do
|
||||||
remote="origin"
|
remote="origin"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
-s|--separator )
|
|
||||||
if [[ -n $2 ]] && [[ $2 != -- ]]
|
|
||||||
then
|
|
||||||
branch_separator=$2
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
echo >&2 "option $1 requires a value"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
--squash )
|
--squash )
|
||||||
merge_mode="--squash"
|
merge_mode="--squash"
|
||||||
;;
|
;;
|
||||||
|
|
@ -54,17 +36,8 @@ do
|
||||||
start_point=$2
|
start_point=$2
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
-- )
|
|
||||||
# terminate argument parsing
|
|
||||||
shift
|
|
||||||
argv+=("$@")
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
finish )
|
|
||||||
finish=true
|
|
||||||
;;
|
|
||||||
* )
|
* )
|
||||||
argv+=("$1")
|
argv+=($1)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
|
|
@ -72,34 +45,38 @@ done
|
||||||
|
|
||||||
concatargs() {
|
concatargs() {
|
||||||
str=$(IFS='-'; echo "$*")
|
str=$(IFS='-'; echo "$*")
|
||||||
branch="$branch_prefix$branch_separator$str"
|
branch="$branch_prefix"/$str
|
||||||
}
|
}
|
||||||
|
|
||||||
test -z "${argv[0]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
|
if test "${argv[0]}" = "finish"; then
|
||||||
|
test -z "${argv[1]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
|
||||||
concatargs "${argv[@]}"
|
branch="$branch_prefix"/"${argv[1]}"
|
||||||
|
|
||||||
if "${finish}"
|
|
||||||
then
|
|
||||||
git merge ${merge_mode} "$branch" && git delete-branch "$branch"
|
git merge ${merge_mode} "$branch" && git delete-branch "$branch"
|
||||||
else
|
else
|
||||||
|
test -z "${argv[0]}" && echo "$branch_prefix" "<name> required." 1>&2 && exit 1
|
||||||
|
if test -n "${argv[1]}"; then
|
||||||
|
concatargs "${argv[@]}"
|
||||||
|
else
|
||||||
|
branch="$branch_prefix"/"${argv[0]}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -n $remote ]] && [[ -z $start_point ]]
|
if [[ -n $remote ]] && [[ -z $start_point ]]
|
||||||
then
|
then
|
||||||
git create-branch -r "$remote" "$branch"
|
git create-branch -r $remote $branch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $remote ]] && [[ -z $start_point ]]
|
if [[ -z $remote ]] && [[ -z $start_point ]]
|
||||||
then
|
then
|
||||||
git create-branch "$branch"
|
git create-branch $branch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n $remote ]] && [[ -n $start_point ]]
|
if [[ -n $remote ]] && [[ -n $start_point ]]
|
||||||
then
|
then
|
||||||
git create-branch -r "$remote" --from "$start_point" "$branch"
|
git create-branch -r $remote --from $start_point $branch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $remote ]] && [[ -n $start_point ]]
|
if [[ -z $remote ]] && [[ -n $start_point ]]
|
||||||
then
|
then
|
||||||
git create-branch --from "$start_point" "$branch"
|
git create-branch --from $start_point $branch
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -63,21 +63,21 @@ main() {
|
||||||
|
|
||||||
if [ -d "${destination_path}/.git" ]; then
|
if [ -d "${destination_path}/.git" ]; then
|
||||||
(
|
(
|
||||||
cd "${destination_path}"
|
cd ${destination_path}
|
||||||
|
|
||||||
# Delete all remotes
|
# Delete all remotes
|
||||||
for remote in $(git remote); do
|
for remote in `git remote`; do
|
||||||
git remote rm "${remote}"
|
git remote rm ${remote}
|
||||||
done
|
done
|
||||||
|
|
||||||
# Add origin
|
# Add origin
|
||||||
git remote add origin "${remote_url}"
|
git remote add origin ${remote_url}
|
||||||
git fetch origin
|
git fetch origin
|
||||||
|
|
||||||
# Set default branch
|
# Set default branch
|
||||||
if [ -z "${branch:-}" ]; then
|
if [ -z "${branch:-}" ]; then
|
||||||
branch=$(LC_ALL=C git remote show origin | grep -oP '(?<=HEAD branch: )[^ ]+$')
|
branch=`LC_ALL=C git remote show origin | grep -oP '(?<=HEAD branch: )[^ ]+$'`
|
||||||
git remote set-head origin "${branch}"
|
git remote set-head origin ${branch}
|
||||||
else
|
else
|
||||||
git remote set-head origin -a
|
git remote set-head origin -a
|
||||||
fi
|
fi
|
||||||
|
|
@ -87,20 +87,19 @@ main() {
|
||||||
git reset --hard HEAD
|
git reset --hard HEAD
|
||||||
|
|
||||||
# Get on the desired branch
|
# Get on the desired branch
|
||||||
git checkout "${branch}"
|
git checkout ${branch}
|
||||||
git reset --hard "origin/${branch}"
|
git reset --hard origin/${branch}
|
||||||
|
|
||||||
# Delete all other branches
|
# Delete all other branches
|
||||||
# shellcheck disable=SC2063
|
branches=`git branch | grep -v \* | xargs`
|
||||||
branches=$(git branch | grep -v '*' | xargs)
|
|
||||||
if [ -n "${branches}" ]; then
|
if [ -n "${branches}" ]; then
|
||||||
git branch -D "${branches}"
|
git branch -D ${branches}
|
||||||
fi
|
fi
|
||||||
)
|
)
|
||||||
elif [ -n "${branch:-}" ]; then
|
elif [ -n "${branch:-}" ]; then
|
||||||
git clone -b "${branch}" "${remote_url}" "${destination_path}"
|
git clone -b ${branch} ${remote_url} ${destination_path}
|
||||||
else
|
else
|
||||||
git clone "${remote_url}" "${destination_path}"
|
git clone ${remote_url} ${destination_path}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
bin/git-fork
21
bin/git-fork
|
|
@ -12,18 +12,18 @@ test -z "$url" && abort "github repo needs to be specified as an argument"
|
||||||
|
|
||||||
# validate user
|
# validate user
|
||||||
echo "Enter your github username"
|
echo "Enter your github username"
|
||||||
read -r user
|
read user
|
||||||
[ -n "$user" ] || abort "git username required"
|
[ -n "$user" ] || abort "git username required"
|
||||||
# personal access token
|
# personal access token
|
||||||
# config name is github-personal-access-token '_' is not allowed in git config
|
# config name is github-personal-access-token '_' is not allowed in git config
|
||||||
|
|
||||||
github_personal_access_token=$(git config --default "$GITHUB_TOKEN" git-extras.github-personal-access-token)
|
github_personal_access_token=$(git config git-extras.github-personal-access-token)
|
||||||
|
|
||||||
test -z "$github_personal_access_token" && abort "GITHUB_TOKEN, or git config git-extras.github-personal-access-token required"
|
test -z "$github_personal_access_token" && abort "git config git-extras.github-personal-access-token required"
|
||||||
|
|
||||||
# extract owner + project from repo url
|
# extract owner + project from repo url
|
||||||
project=${url##*/}
|
project=${url##*/}
|
||||||
owner=${url%/"$project"}
|
owner=${url%/$project}
|
||||||
project=${project%.git}
|
project=${project%.git}
|
||||||
if [[ $owner == git@* ]]; then
|
if [[ $owner == git@* ]]; then
|
||||||
owner=${owner##*:}
|
owner=${owner##*:}
|
||||||
|
|
@ -32,20 +32,19 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# validate
|
# validate
|
||||||
[[ -z "$project" || -z "$owner" ]] && abort "github repo needs to be specified as an argument"
|
[ -z "$project" -o -z "$owner" ] && abort "github repo needs to be specified as an argument"
|
||||||
|
|
||||||
# create fork
|
# create fork
|
||||||
if ! curl -qsf \
|
curl -qsf \
|
||||||
-X POST \
|
-X POST \
|
||||||
-u "$user:$github_personal_access_token" \
|
-u "$user:$github_personal_access_token" \
|
||||||
-H "X-GitHub-OTP: $MFA_CODE" \
|
-H "X-GitHub-OTP: $MFA_CODE" \
|
||||||
"https://api.github.com/repos/$owner/$project/forks"
|
"https://api.github.com/repos/$owner/$project/forks"
|
||||||
then
|
|
||||||
abort "fork failed"
|
[ $? = 0 ] || abort "fork failed"
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Add GitHub remote branch via SSH (you will be prompted to verify the server's credentials)? (y/n)"
|
echo "Add GitHub remote branch via SSH (you will be prompted to verify the server's credentials)? (y/n)"
|
||||||
read -r use_ssh
|
read use_ssh
|
||||||
# Check if user has ssh configured with GitHub
|
# Check if user has ssh configured with GitHub
|
||||||
if [ -n "$use_ssh" ] && ssh -T git@github.com 2>&1 | grep -qi 'success'; then
|
if [ -n "$use_ssh" ] && ssh -T git@github.com 2>&1 | grep -qi 'success'; then
|
||||||
remote_prefix="git@github.com:"
|
remote_prefix="git@github.com:"
|
||||||
|
|
@ -61,7 +60,7 @@ else
|
||||||
# clone forked repo into current dir
|
# clone forked repo into current dir
|
||||||
git clone "${remote_prefix}${user}/${project}.git" "$project"
|
git clone "${remote_prefix}${user}/${project}.git" "$project"
|
||||||
# add reference to origin fork so can merge in upstream changes
|
# add reference to origin fork so can merge in upstream changes
|
||||||
cd "$project" || exit
|
cd "$project"
|
||||||
git remote add upstream "${remote_prefix}${owner}/${project}.git"
|
git remote add upstream "${remote_prefix}${owner}/${project}.git"
|
||||||
git fetch upstream
|
git fetch upstream
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
branch=$1
|
branch=$1
|
||||||
|
|
||||||
test -z "$branch" && echo "branch required." 1>&2 && exit 1
|
test -z $branch && echo "branch required." 1>&2 && exit 1
|
||||||
|
|
||||||
changes=$(git status --porcelain)
|
changes=`git status --porcelain`
|
||||||
|
|
||||||
clean()
|
clean()
|
||||||
{
|
{
|
||||||
git symbolic-ref HEAD "refs/heads/$branch"
|
git symbolic-ref HEAD refs/heads/$branch
|
||||||
rm .git/index
|
rm .git/index
|
||||||
git clean -fdx
|
git clean -fdx
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -n "$changes" ]; then
|
if [ ! -z "$changes" ]; then
|
||||||
read -rp "All untracked changes will be lost. Continue [y/N]? " res
|
read -p "All untracked changes will be lost. Continue [y/N]? " res
|
||||||
case $res in
|
case $res in
|
||||||
[Yy]* ) ;;
|
[Yy]* ) ;;
|
||||||
* ) exit 0;;
|
* ) exit 0;;
|
||||||
|
|
|
||||||
40
bin/git-get
40
bin/git-get
|
|
@ -1,40 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
_usage() {
|
|
||||||
printf '%s\n' "usage: ${0##*/} <url>
|
|
||||||
usage: ${0##*/} --help
|
|
||||||
|
|
||||||
Clone a repository in a particular directory."
|
|
||||||
}
|
|
||||||
|
|
||||||
if (( $# == 0 )); then
|
|
||||||
_usage
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
for arg; do
|
|
||||||
if [ "$arg" = '-h' ] || [ "$arg" = '--help' ]; then
|
|
||||||
_usage
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
url=$1
|
|
||||||
if ! shift; then
|
|
||||||
printf 'ERROR: Failed to shift' >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
clone_path=$(git config --get git-extras.get.clone-path)
|
|
||||||
|
|
||||||
if [ -z "$clone_path" ]; then
|
|
||||||
printf 'ERROR: %s\n' "Git configuration key 'git-extras.get.clone-path' must be set to a directory to clone under" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
dirname=${url%/}
|
|
||||||
dirname=${dirname%.git}
|
|
||||||
dirname=${dirname##*/}
|
|
||||||
|
|
||||||
mkdir -p "$clone_path"
|
|
||||||
git clone "$url" "$clone_path/$dirname" "$@"
|
|
||||||
|
|
@ -4,10 +4,10 @@ echo 'setting up gh-pages'
|
||||||
echo '-------------------'
|
echo '-------------------'
|
||||||
|
|
||||||
echo 'Tell me your github account username: '
|
echo 'Tell me your github account username: '
|
||||||
read -r username
|
read username
|
||||||
|
|
||||||
echo 'Now, tell me your repository name: '
|
echo 'Now, tell me your repository name: '
|
||||||
read -r repository
|
read repository
|
||||||
|
|
||||||
git stash \
|
git stash \
|
||||||
&& git checkout -b 'gh-pages' \
|
&& git checkout -b 'gh-pages' \
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
src=$1
|
src=$1
|
||||||
dst=$2
|
dst=$2
|
||||||
|
|
||||||
test -z "$src" && echo "source branch required." 1>&2 && exit 1
|
test -z $src && echo "source branch required." 1>&2 && exit 1
|
||||||
test -z "$dst" && echo "destination branch required." 1>&2 && exit 1
|
test -z $dst && echo "destination branch required." 1>&2 && exit 1
|
||||||
|
|
||||||
git checkout "$dst" \
|
git checkout $dst \
|
||||||
&& git merge --no-ff "$src" \
|
&& git merge --no-ff $src \
|
||||||
&& git branch -d "$src"
|
&& git branch -d $src
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
for param in "$@"
|
for param in $*
|
||||||
do
|
do
|
||||||
case $param in
|
case $param in
|
||||||
-h)
|
-h)
|
||||||
|
|
@ -31,7 +31,7 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
cd "$(git-root)" || exit # cd for git blame
|
cd "$(git-root)" # cd for git blame
|
||||||
MERGED_LOG=$(git_extra_mktemp)
|
MERGED_LOG=$(git_extra_mktemp)
|
||||||
if [[ $EMAIL == '-e' ]]
|
if [[ $EMAIL == '-e' ]]
|
||||||
then
|
then
|
||||||
|
|
@ -44,13 +44,11 @@ for file in $(git diff --name-only "$@")
|
||||||
do
|
do
|
||||||
test -n "$DEBUG" && echo "git blame $file"
|
test -n "$DEBUG" && echo "git blame $file"
|
||||||
# $1 - since $2 - until
|
# $1 - since $2 - until
|
||||||
# shellcheck disable=SC2086
|
git blame $NOT_WHITESPACE --line-porcelain "$1" -- "$file" 2> /dev/null |
|
||||||
git blame $NOT_WHITESPACE --line-porcelain "$1" -- "$file" 2> /dev/null |
|
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/- \1/' >> $MERGED_LOG
|
||||||
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/- \1/' >> "$MERGED_LOG"
|
|
||||||
# if $2 not given, use current commit as "until"
|
# if $2 not given, use current commit as "until"
|
||||||
# shellcheck disable=SC2086
|
|
||||||
git blame $NOT_WHITESPACE --line-porcelain "${2-@}" -- "$file" 2> /dev/null |
|
git blame $NOT_WHITESPACE --line-porcelain "${2-@}" -- "$file" 2> /dev/null |
|
||||||
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/+ \1/' >> "$MERGED_LOG"
|
LC_ALL=C sed -n "$PATTERN" | sort | uniq -c | LC_ALL=C sed 's/^\(.\)/+ \1/' >> $MERGED_LOG
|
||||||
done
|
done
|
||||||
|
|
||||||
DEBUG="$DEBUG" awk '
|
DEBUG="$DEBUG" awk '
|
||||||
|
|
@ -73,8 +71,8 @@ END {
|
||||||
printf("%d %s\n", contributors[people], people)
|
printf("%d %s\n", contributors[people], people)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}' "$MERGED_LOG" | sort -nr | # only gawk supports built-in sort function
|
}' $MERGED_LOG | sort -nr | # only gawk supports built-in sort function
|
||||||
while read -r line
|
while read line
|
||||||
do
|
do
|
||||||
people=${line#* }
|
people=${line#* }
|
||||||
num=${line%% *}
|
num=${line%% *}
|
||||||
|
|
@ -89,7 +87,7 @@ do
|
||||||
do
|
do
|
||||||
printf "+"
|
printf "+"
|
||||||
done
|
done
|
||||||
printf "(%s)" "$num"
|
printf "(%s)" $num
|
||||||
else
|
else
|
||||||
for (( i = 0; i < num; i++ ))
|
for (( i = 0; i < num; i++ ))
|
||||||
do
|
do
|
||||||
|
|
@ -105,7 +103,7 @@ do
|
||||||
do
|
do
|
||||||
printf "-"
|
printf "-"
|
||||||
done
|
done
|
||||||
printf "(%s)" "$num"
|
printf "(%s)" $num
|
||||||
else
|
else
|
||||||
for (( i = 0; i > num; i-- ))
|
for (( i = 0; i > num; i-- ))
|
||||||
do
|
do
|
||||||
|
|
|
||||||
258
bin/git-ignore
258
bin/git-ignore
|
|
@ -1,28 +1,8 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
|
: ${GIT_DIR:=$(git rev-parse --git-dir)}
|
||||||
|
|
||||||
# awk script that takes 2 input files. The first one is newline deilmeted
|
function show_contents {
|
||||||
# string of patterns to look for, second one is the file to remove them from.
|
|
||||||
# outfile has to be passed with -v upon call and is the file result is
|
|
||||||
# written to.
|
|
||||||
read -r -d '' AWK_SCRIPT <<'EOF'
|
|
||||||
# process the first "file" (newline split argument list)
|
|
||||||
NR==FNR { a[b++]=$0; next; }
|
|
||||||
# process file
|
|
||||||
{
|
|
||||||
found=0;
|
|
||||||
for (i=0; i != b; i++) {
|
|
||||||
if (a[i] == $0) { found=1; }
|
|
||||||
}
|
|
||||||
if (found == 1) { print "... removing '"$0"'"; }
|
|
||||||
else { print $0 > outfile }
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
show_contents() {
|
|
||||||
local file="${2/#~/$HOME}"
|
local file="${2/#~/$HOME}"
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
echo "$1 gitignore: $2" && cat "$file"
|
echo "$1 gitignore: $2" && cat "$file"
|
||||||
|
|
@ -31,41 +11,18 @@ show_contents() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
cd_to_git_root() {
|
function global_ignore() {
|
||||||
local error_level="$1"
|
git config --global core.excludesFile || \
|
||||||
|
([ -n "$XDG_CONFIG_HOME" ] && echo "$XDG_CONFIG_HOME/git/ignore") || \
|
||||||
if ! git rev-parse --git-dir &>/dev/null; then
|
echo "$HOME/.config/git/ignore"
|
||||||
if [ "$error_level" = '--warn' ]; then
|
|
||||||
echo "Warning: Not currently in a Git repository" >&2
|
|
||||||
elif [ "$error_level" = '--error' ]; then
|
|
||||||
echo "Error: Not currently in a Git repository" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local result=
|
|
||||||
if result=$(git rev-parse --show-toplevel 2>/dev/null); then
|
|
||||||
cd "$result" || exit
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global_ignore() {
|
function show_global {
|
||||||
if ! git config --global core.excludesFile 2>/dev/null; then
|
|
||||||
if [ -f "$HOME/.gitignore" ]; then
|
|
||||||
echo "$HOME/.gitignore"
|
|
||||||
else
|
|
||||||
echo "${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
show_global() {
|
|
||||||
show_contents Global "$(global_ignore)"
|
show_contents Global "$(global_ignore)"
|
||||||
}
|
}
|
||||||
|
|
||||||
add_global() {
|
function add_global {
|
||||||
local global_gitignore
|
local global_gitignore="$(global_ignore)"
|
||||||
global_gitignore="$(global_ignore)"
|
|
||||||
if [ -z "$global_gitignore" ]; then
|
if [ -z "$global_gitignore" ]; then
|
||||||
echo "Can't find global .gitignore."
|
echo "Can't find global .gitignore."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -76,28 +33,28 @@ add_global() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
show_local() {
|
function show_local {
|
||||||
cd_to_git_root --warn
|
cd "$(git root)"
|
||||||
show_contents Local .gitignore
|
show_contents Local .gitignore
|
||||||
}
|
}
|
||||||
|
|
||||||
add_local() {
|
function add_local {
|
||||||
cd_to_git_root --warn
|
cd "$(git root)"
|
||||||
add_patterns .gitignore "$@"
|
add_patterns .gitignore "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
show_private() {
|
function show_private {
|
||||||
cd_to_git_root --error
|
cd "$(git root)"
|
||||||
show_contents Private "${GIT_DIR}/info/exclude"
|
show_contents Private "${GIT_DIR}/info/exclude"
|
||||||
}
|
}
|
||||||
|
|
||||||
add_private() {
|
function add_private {
|
||||||
cd_to_git_root --error
|
cd "$(git root)"
|
||||||
test -d "${GIT_DIR}/info" || mkdir -p "${GIT_DIR}/info"
|
test -d "${GIT_DIR}/info" || mkdir -p "${GIT_DIR}/info"
|
||||||
add_patterns "${GIT_DIR}/info/exclude" "$@"
|
add_patterns "${GIT_DIR}/info/exclude" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
add_patterns() {
|
function add_patterns {
|
||||||
echo "Adding pattern(s) to: $1"
|
echo "Adding pattern(s) to: $1"
|
||||||
local file="${1/#~/$HOME}"
|
local file="${1/#~/$HOME}"
|
||||||
dir_name=$(dirname "$file")
|
dir_name=$(dirname "$file")
|
||||||
|
|
@ -114,66 +71,6 @@ add_patterns() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
edit_file() {
|
|
||||||
local file="${2/#~/$HOME}"
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
echo "Editing $1 gitignore: ($2)" && eval "$(git var GIT_EDITOR) $(printf '%q' "$file")"
|
|
||||||
echo "Done."
|
|
||||||
else
|
|
||||||
echo "There is no $1 .gitignore yet." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_usage() {
|
|
||||||
cat << EOF
|
|
||||||
Usage: git ignore [OPTION]... [PATTERN]...
|
|
||||||
Modify or display local global or private gitignore files.
|
|
||||||
|
|
||||||
OPTIONs set context (local, global, private) and action (display, add,
|
|
||||||
remove, edit). In case of collision, last flag overwrites preceding ones.
|
|
||||||
Defaults are: local context, action is display (see man git ignore for
|
|
||||||
more details).
|
|
||||||
Context examples:
|
|
||||||
local: .../repo/.gitignore
|
|
||||||
private: .../repo/.git/info/exclude
|
|
||||||
global: \$HOME/.gitignore
|
|
||||||
|
|
||||||
PATTERNs are the gitignore patterns as specified in git documentation.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-l, --local Set context to local gitignore
|
|
||||||
-g, --global Set context to global gitignore
|
|
||||||
-p, --private Set context to private gitignore
|
|
||||||
-e, --edit Set action to edit
|
|
||||||
-r, --remove Set action to remove
|
|
||||||
-h, --help Print this message
|
|
||||||
-- End of options delimiter
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_patterns() {
|
|
||||||
declare -a args
|
|
||||||
local tmpfile
|
|
||||||
args=( "${@:3}" )
|
|
||||||
local file="${2/#~/$HOME}"
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
tmpfile="$(mktemp -q "${TMPDIR:-/tmp}"/git-extras-ignore.XXXXXX 2>/dev/null)"
|
|
||||||
echo "Removing patterns from $1 gitignore: $2"
|
|
||||||
awk -v outfile="$tmpfile" "${AWK_SCRIPT}"\
|
|
||||||
<(printf '%s\n' "${args[@]}") "$file"
|
|
||||||
cat "$tmpfile" > "$file"
|
|
||||||
rm "$tmpfile"
|
|
||||||
else
|
|
||||||
echo "There is no $1 .gitignore yet"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# can have only 1 action and 1 level, if conflicting flags are passed
|
|
||||||
# latter ones overwrite former
|
|
||||||
# sanity of args not tested (e.g. there should be no args if -e is supplied)
|
|
||||||
if test $# -eq 0; then
|
if test $# -eq 0; then
|
||||||
show_global
|
show_global
|
||||||
echo "---------------------------------"
|
echo "---------------------------------"
|
||||||
|
|
@ -181,105 +78,22 @@ if test $# -eq 0; then
|
||||||
echo "---------------------------------"
|
echo "---------------------------------"
|
||||||
show_private
|
show_private
|
||||||
else
|
else
|
||||||
# parse flags and args
|
case "$1" in
|
||||||
level="none"
|
-l|--local)
|
||||||
action="none"
|
test $# -gt 1 && add_local "${@:2}" && echo
|
||||||
declare -a args
|
show_local
|
||||||
while [ $# -gt 0 ]; do
|
;;
|
||||||
case "$1" in
|
-g|--global)
|
||||||
-h|--help)
|
test $# -gt 1 && add_global "${@:2}" && echo
|
||||||
_usage
|
show_global
|
||||||
exit 0
|
;;
|
||||||
;;
|
-p|--private)
|
||||||
-l|--local)
|
test $# -gt 1 && add_private "${@:2}" && echo
|
||||||
level="local"
|
show_private
|
||||||
;;
|
;;
|
||||||
-g|--global)
|
*)
|
||||||
level="global"
|
add_local "$@"
|
||||||
;;
|
;;
|
||||||
-p|--private)
|
esac
|
||||||
level="private"
|
|
||||||
;;
|
|
||||||
-e|--edit)
|
|
||||||
action="edit"
|
|
||||||
;;
|
|
||||||
-r|--remove)
|
|
||||||
action="remove"
|
|
||||||
;;
|
|
||||||
--)
|
|
||||||
shift
|
|
||||||
args+=("$@")
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
args+=("$1")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
# compatible with previous version
|
|
||||||
if [ "$action" = "none" ]; then
|
|
||||||
case "$level" in
|
|
||||||
local)
|
|
||||||
test ${#args[@]} -ne 0 && add_local "${args[@]}" && echo
|
|
||||||
show_local
|
|
||||||
;;
|
|
||||||
global)
|
|
||||||
test ${#args[@]} -ne 0 && add_global "${args[@]}" && echo
|
|
||||||
show_global
|
|
||||||
;;
|
|
||||||
private)
|
|
||||||
test ${#args[@]} -ne 0 && add_private "${args[@]}" && echo
|
|
||||||
show_private
|
|
||||||
;;
|
|
||||||
none)
|
|
||||||
add_local "${args[@]}"
|
|
||||||
# maybe show_local here too?
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
# open file in editor
|
|
||||||
elif [ "$action" = "edit" ]; then
|
|
||||||
case "$level" in
|
|
||||||
local|none)
|
|
||||||
cd_to_git_root --warn
|
|
||||||
edit_file 'local' .gitignore && echo
|
|
||||||
;;
|
|
||||||
global)
|
|
||||||
global_gitignore="$(global_ignore)"
|
|
||||||
edit_file global "$global_gitignore" && echo
|
|
||||||
;;
|
|
||||||
private)
|
|
||||||
cd_to_git_root --error
|
|
||||||
test -d "${GIT_DIR}/info" || mkdir -p "${GIT_DIR}/info"
|
|
||||||
edit_file private "${GIT_DIR}/info/exclude" && echo
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
# remove entries
|
|
||||||
else
|
|
||||||
if [ ${#args[@]} -eq 0 ]; then
|
|
||||||
echo "Nothing to remove."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
case "$level" in
|
|
||||||
local|none)
|
|
||||||
cd_to_git_root --warn
|
|
||||||
remove_patterns 'local' .gitignore "${args[@]}" && echo
|
|
||||||
show_local
|
|
||||||
;;
|
|
||||||
global)
|
|
||||||
global_gitignore="$(global_ignore)"
|
|
||||||
remove_patterns global "$global_gitignore" "${args[@]}" && echo
|
|
||||||
show_global
|
|
||||||
;;
|
|
||||||
private)
|
|
||||||
cd_to_git_root --error
|
|
||||||
remove_patterns private "${GIT_DIR}/info/exclude" "${args[@]}" && echo
|
|
||||||
show_private
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
gitignore_io_url="https://www.toptal.com/developers/gitignore/api/"
|
gitignore_io_url="https://www.gitignore.io/api/"
|
||||||
default_path="$HOME/.gi_list"
|
default_path="$HOME/.gi_list"
|
||||||
if [[ -n "$XDG_CACHE_HOME" ]]; then
|
if [[ -n "$XDG_CACHE_HOME" ]]; then
|
||||||
default_path="$XDG_CACHE_HOME/git-extras/gi_list"
|
default_path="$XDG_CACHE_HOME/git-extras/gi_list"
|
||||||
|
|
@ -17,7 +17,7 @@ print_in_alphabetical_order() {
|
||||||
for ignorable in $(echo "$gi_list" | sort);
|
for ignorable in $(echo "$gi_list" | sort);
|
||||||
do
|
do
|
||||||
first_character=${ignorable:0:1}
|
first_character=${ignorable:0:1}
|
||||||
if [[ $first_character = "$previous_first_character" ]]; then
|
if [[ $first_character = $previous_first_character ]]; then
|
||||||
printf " %s" "$ignorable"
|
printf " %s" "$ignorable"
|
||||||
elif [[ $first = true ]]; then
|
elif [[ $first = true ]]; then
|
||||||
previous_first_character=$first_character
|
previous_first_character=$first_character
|
||||||
|
|
@ -46,11 +46,12 @@ search() {
|
||||||
}
|
}
|
||||||
|
|
||||||
print_last_modified_time() {
|
print_last_modified_time() {
|
||||||
if ! gi_list_date=$(stat -c "%y" "$default_path" 2> /dev/null); then
|
gi_list_date=$(stat -c "%y" "$default_path" 2> /dev/null)
|
||||||
if ! gi_list_date=$(stat -f "%t%Sm" "$default_path" 2> /dev/null); then
|
if [ "$?" -ne 0 ]; then
|
||||||
if ! gi_list_date=$(date -r "$default_path" +%s 2> /dev/null); then
|
gi_list_date=$(stat -f "%t%Sm" "$default_path" 2> /dev/null)
|
||||||
gi_list_date=0
|
if [ "$?" -ne 0 ]; then
|
||||||
fi
|
gi_list_date=$(date -r "$default_path" +%s 2> /dev/null)
|
||||||
|
[ "$?" -ne 0 ] && gi_list_date=0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo "Last update time: $gi_list_date"
|
echo "Last update time: $gi_list_date"
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ echon "${COLOR_TITLE}## Local Branches:${NORMAL}"
|
||||||
echon "$(local_branches)"
|
echon "$(local_branches)"
|
||||||
|
|
||||||
SUBMODULES_LOG=$(submodules)
|
SUBMODULES_LOG=$(submodules)
|
||||||
if [ -n "$SUBMODULES_LOG" ]; then
|
if [ ! -z "$SUBMODULES_LOG" ]; then
|
||||||
echon "${COLOR_TITLE}## Submodule(s):${NORMAL}"
|
echon "${COLOR_TITLE}## Submodule(s):${NORMAL}"
|
||||||
echon "$SUBMODULES_LOG"
|
echon "$SUBMODULES_LOG"
|
||||||
fi
|
fi
|
||||||
|
|
@ -73,7 +73,7 @@ fi
|
||||||
echon "${COLOR_TITLE}## Most Recent Commit:${NORMAL}"
|
echon "${COLOR_TITLE}## Most Recent Commit:${NORMAL}"
|
||||||
echon "$(most_recent_commit)"
|
echon "$(most_recent_commit)"
|
||||||
|
|
||||||
if [ -n "$HIDE_CONFIG" ]; then
|
if [ ! -z "$HIDE_CONFIG" ]; then
|
||||||
echon "${COLOR_TITLE}## Configuration (.git/config):${NORMAL}"
|
echon "${COLOR_TITLE}## Configuration (.git/config):${NORMAL}"
|
||||||
echon "$(get_config)"
|
echon "$(get_config)"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
git log "@{upstream}..@" "$@"
|
git log @{upstream}..@ $*
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,10 @@ while getopts "m:eapfh" arg; do
|
||||||
PUSH=true
|
PUSH=true
|
||||||
;;
|
;;
|
||||||
f)
|
f)
|
||||||
FORCE='--force-with-lease'
|
FORCE='-f'
|
||||||
;;
|
;;
|
||||||
h)
|
h)
|
||||||
echo "$USAGE"
|
echo $USAGE
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
?)
|
?)
|
||||||
|
|
@ -46,7 +46,7 @@ done
|
||||||
shift $((OPTIND-1))
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
if [[ $# != 0 ]]; then
|
if [[ $# != 0 ]]; then
|
||||||
echo "Unknown arguments: $*"
|
echo "Unknown arguments: $@"
|
||||||
echo "${USAGE}"
|
echo "${USAGE}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
@ -54,19 +54,19 @@ fi
|
||||||
set -- "${ARGS[@]}" # restore positional parameters
|
set -- "${ARGS[@]}" # restore positional parameters
|
||||||
|
|
||||||
if [[ $ALL == true ]]; then
|
if [[ $ALL == true ]]; then
|
||||||
|
|
||||||
# Check if there is no changes to stage
|
# Check if there is no changes to stage
|
||||||
if [[ -z $(git status --porcelain) ]]; then
|
if [[ -z $(git status --porcelain) ]]; then
|
||||||
echo "No changes to commit"
|
echo "No changes to commit"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get confirmation from user
|
# Get confirmation from user
|
||||||
git status
|
git status
|
||||||
echo "Everything will be added"
|
echo "Everything will be added"
|
||||||
read -rp "Press enter to continue"
|
read -p "Press enter to continue"
|
||||||
|
|
||||||
# Restore staging area so that, for example,
|
# Restore staging area so that, for example,
|
||||||
# add and modify will not be separate entries in status
|
# add and modify will not be separate entries in status
|
||||||
git restore --staged . || true
|
git restore --staged . || true
|
||||||
git add .
|
git add .
|
||||||
|
|
@ -79,7 +79,7 @@ if [[ $PUSH == true ]]; then
|
||||||
git push $FORCE
|
git push $FORCE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --no-edit by default. use option -e to override this
|
# --no-edit by default. use option -e to override this
|
||||||
|
|
||||||
# Arguments are passed with quoted "$@" to avoid misparsing
|
# Arguments are passed with quoted "$@" to avoid misparsing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ then
|
||||||
git stash
|
git stash
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${!#}" = '--ff-only' ]; then
|
if [ "${!#}" == '--ff-only' ]; then
|
||||||
case $# in
|
case $# in
|
||||||
2 ) # dest --ff
|
2 ) # dest --ff
|
||||||
git push "$(git rev-parse --show-toplevel)" "$cur_branch":"$1";;
|
git push "$(git rev-parse --show-toplevel)" "$cur_branch":"$1";;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ branch=$2
|
||||||
prefix=$3
|
prefix=$3
|
||||||
flat=0
|
flat=0
|
||||||
|
|
||||||
if test "$prefix" = "."; then
|
if test $prefix = "."; then
|
||||||
prefix=$(mktemp -u 'git-merge-repo.XXXXXXX')
|
prefix=$(mktemp -u 'git-merge-repo.XXXXXXX')
|
||||||
flat=1
|
flat=1
|
||||||
fi
|
fi
|
||||||
|
|
@ -16,10 +16,10 @@ message=$(git log -1 --pretty=%B)
|
||||||
|
|
||||||
if test $flat -eq 1; then
|
if test $flat -eq 1; then
|
||||||
git stash -u
|
git stash -u
|
||||||
mv -i "$prefix"/* ./
|
mv -i $prefix/* ./
|
||||||
git undo
|
git undo
|
||||||
git add .
|
git add .
|
||||||
git commit -am "$message"
|
git commit -am "$message"
|
||||||
git stash apply
|
git stash apply
|
||||||
rm -drf "$prefix"
|
rm -drf $prefix
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo 1>&2 "usage: git missing [<first branch>] <second branch> [<git log options>] [[--] <path>...]"
|
echo 1>&2 "usage: git missing [<first branch>] <second branch> [<git log options>]"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "${#}" -lt 1 ]
|
if [ "${#}" -lt 1 ]
|
||||||
|
|
@ -12,20 +12,9 @@ fi
|
||||||
|
|
||||||
declare -a git_log_args=()
|
declare -a git_log_args=()
|
||||||
declare -a branches=()
|
declare -a branches=()
|
||||||
declare -a pathspec=()
|
|
||||||
declare parse_path=false
|
|
||||||
|
|
||||||
for arg in "$@" ; do
|
for arg in "$@" ; do
|
||||||
|
|
||||||
if [[ $parse_path == true ]]; then
|
|
||||||
pathspec+=("$@")
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
--)
|
|
||||||
parse_path=true
|
|
||||||
;;
|
|
||||||
--*)
|
--*)
|
||||||
git_log_args+=( "$arg" )
|
git_log_args+=( "$arg" )
|
||||||
;;
|
;;
|
||||||
|
|
@ -49,4 +38,4 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git log "${git_log_args[@]}" "$firstbranch"..."$secondbranch" --format="%m %h %s" --left-right -- "${pathspec[@]}"
|
git log "${git_log_args[@]}" "$firstbranch"..."$secondbranch" --format="%m %h %s" --left-right
|
||||||
|
|
|
||||||
22
bin/git-mr
22
bin/git-mr
|
|
@ -7,30 +7,22 @@ if [ -z "${1-}" ] ; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
remote_ref_kind=merge-requests
|
|
||||||
|
|
||||||
if test "$1" = "clean"; then
|
if test "$1" = "clean"; then
|
||||||
git for-each-ref refs/heads/mr/* --format='%(refname)' | while read -r ref; do
|
git for-each-ref refs/heads/mr/* --format='%(refname)' | while read ref; do
|
||||||
git branch -D "${ref#refs/heads/}"
|
git branch -D ${ref#refs/heads/}
|
||||||
done
|
done
|
||||||
exit 0
|
exit 0
|
||||||
elif [[ $1 =~ ^(https?://[^/]+/(.+))/merge_requests/([0-9]+).*$ ]]; then
|
elif [[ $1 =~ ^(https?://[^/]+/(.+))/merge_requests/([0-9]+).*$ ]]; then
|
||||||
remote=${BASH_REMATCH[1]}.git
|
remote=${BASH_REMATCH[1]}.git
|
||||||
id=${BASH_REMATCH[3]}
|
id=${BASH_REMATCH[3]}
|
||||||
elif [[ $1 =~ ^(https?://[^/]+/(.+))/pulls/([0-9]+).*$ ]]; then
|
|
||||||
# Forgejo/Codeberg pull request URL, e.g.
|
|
||||||
# https://codeberg.org/owner/repository/pulls/453
|
|
||||||
remote=${BASH_REMATCH[1]}.git
|
|
||||||
id=${BASH_REMATCH[3]}
|
|
||||||
remote_ref_kind=pull
|
|
||||||
else
|
else
|
||||||
id=$1
|
id=$1
|
||||||
remote=${2:-origin}
|
remote=${2:-origin}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
branch=mr/$id
|
branch=mr/$id
|
||||||
remote_ref=refs/$remote_ref_kind/$id/head
|
remote_ref=refs/merge-requests/$id/head
|
||||||
git fetch -fu "$remote" "$remote_ref:$branch"
|
git fetch -fu $remote $remote_ref:$branch
|
||||||
git checkout "$branch"
|
git checkout $branch
|
||||||
git config --local --replace "branch.$branch.merge" "$remote_ref"
|
git config --local --replace branch.$branch.merge $remote_ref
|
||||||
git config --local --replace "branch.$branch.remote" "$remote"
|
git config --local --replace branch.$branch.remote $remote
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,15 @@ do
|
||||||
file="$file"' '"$i"
|
file="$file"' '"$i"
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
test -n "$*" && range=("$@")
|
test -n "$*" && range="$*"
|
||||||
|
|
||||||
test -z "$file" && echo "file required." 1>&2 && exit 1
|
test -z "$file" && echo "file required." 1>&2 && exit 1
|
||||||
if [ -z "${range[*]}" ]
|
if [ -z "$range" ]
|
||||||
then
|
then
|
||||||
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
|
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
|
||||||
--prune-empty --tag-name-filter cat -- --all
|
--prune-empty --tag-name-filter cat -- --all
|
||||||
else
|
else
|
||||||
# $range is an array so that we can forward multiple rev-list arguments
|
# don't quote $range so that we can forward multiple rev-list arguments
|
||||||
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
|
git filter-branch -f --index-filter "git rm -r --cached ""$file"" --ignore-unmatch" \
|
||||||
--prune-empty --tag-name-filter cat -- "${range[@]}"
|
--prune-empty --tag-name-filter cat -- $range
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
set -e
|
set -e
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
if ! command -v pastebinit &>/dev/null; then
|
if ! command -v pastebinit >/dev/null 2>&1; then
|
||||||
echo >&2 "To run 'git paste', you need to install pastebinit in your system"
|
echo >&2 "To run 'git paste', you need to install pastebinit in your system"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
12
bin/git-pr
12
bin/git-pr
|
|
@ -12,10 +12,10 @@ pull() {
|
||||||
ref="refs/pull/$id/merge"
|
ref="refs/pull/$id/merge"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git fetch -fu "$remote" "$ref:$branch" && \
|
git fetch -fu $remote $ref:$branch && \
|
||||||
git checkout "$branch" && \
|
git checkout $branch && \
|
||||||
git config --local --replace "branch.$branch.merge" "$ref" && \
|
git config --local --replace branch.$branch.merge $ref && \
|
||||||
git config --local --replace "branch.$branch.remote" "$remote"
|
git config --local --replace branch.$branch.remote $remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
pull_pr_if_matched() {
|
pull_pr_if_matched() {
|
||||||
|
|
@ -54,8 +54,8 @@ done
|
||||||
test -z "$1" && echo "pr number required." 1>&2 && exit 1
|
test -z "$1" && echo "pr number required." 1>&2 && exit 1
|
||||||
|
|
||||||
if test "$1" = "clean"; then
|
if test "$1" = "clean"; then
|
||||||
git for-each-ref refs/heads/pr/* --format='%(refname)' | while read -r ref; do
|
git for-each-ref refs/heads/pr/* --format='%(refname)' | while read ref; do
|
||||||
git branch -D "${ref#refs/heads/}"
|
git branch -D ${ref#refs/heads/}
|
||||||
done
|
done
|
||||||
|
|
||||||
elif [[ "$1" =~ ^[0-9]+$ ]]; then
|
elif [[ "$1" =~ ^[0-9]+$ ]]; then
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ SECONDARY_BRANCH=""
|
||||||
FF="--ff"
|
FF="--ff"
|
||||||
CONTINUE="no"
|
CONTINUE="no"
|
||||||
|
|
||||||
current_branch() {
|
function current_branch() {
|
||||||
git rev-parse --abbrev-ref HEAD
|
git rev-parse --abbrev-ref HEAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,10 +19,10 @@ function usage()
|
||||||
echo " -c|--continue: Continue after the user updates conflicts."
|
echo " -c|--continue: Continue after the user updates conflicts."
|
||||||
}
|
}
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]
|
while [[ $# > 0 ]]
|
||||||
do
|
do
|
||||||
key="$1"
|
key="$1"
|
||||||
|
|
||||||
case $key in
|
case $key in
|
||||||
--no-ff)
|
--no-ff)
|
||||||
FF="--no-ff"
|
FF="--no-ff"
|
||||||
|
|
@ -50,17 +50,19 @@ fi
|
||||||
|
|
||||||
if [[ "$CONTINUE" == "yes" ]]; then
|
if [[ "$CONTINUE" == "yes" ]]; then
|
||||||
TARGET_BRANCH=$(current_branch)
|
TARGET_BRANCH=$(current_branch)
|
||||||
SECONDARY_BRANCH=${TARGET_BRANCH%"-rebased-on-top-of-"*}
|
set $(echo "$TARGET_BRANCH" | sed -e "s/-rebased-on-top-of-/\n/g")
|
||||||
PRIMARY_BRANCH=${TARGET_BRANCH#*"-rebased-on-top-of-"}
|
if [[ $# != 2 ]]; then
|
||||||
if [[ "${SECONDARY_BRANCH}-rebased-on-top-of-${PRIMARY_BRANCH}" != $TARGET_BRANCH ]]; then
|
|
||||||
echo "Couldn't continue rebasing on ${TARGET_BRANCH}"
|
echo "Couldn't continue rebasing on ${TARGET_BRANCH}"
|
||||||
exit 30 # Impossible to detect PRIMARY_BRANCH AND SECONDARY_BRANCH
|
exit 30 # Impossible to detect PRIMARY_BRANCH AND SECONDARY_BRANCH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
SECONDARY_BRANCH=$1
|
||||||
|
PRIMARY_BRANCH=$2
|
||||||
|
|
||||||
echo "Continuing rebasing of $SECONDARY_BRANCH on top of $PRIMARY_BRANCH"
|
echo "Continuing rebasing of $SECONDARY_BRANCH on top of $PRIMARY_BRANCH"
|
||||||
git commit || exit 51
|
git commit || exit 51
|
||||||
git branch -d "${SECONDARY_BRANCH}" || exit 52
|
git branch -d ${SECONDARY_BRANCH} || exit 52
|
||||||
git branch -m "${TARGET_BRANCH}" "${SECONDARY_BRANCH}" || exit 53
|
git branch -m ${TARGET_BRANCH} ${SECONDARY_BRANCH} || exit 53
|
||||||
|
|
||||||
elif [[ "$PRIMARY_BRANCH" == "" ]]; then
|
elif [[ "$PRIMARY_BRANCH" == "" ]]; then
|
||||||
usage
|
usage
|
||||||
|
|
@ -69,13 +71,14 @@ else
|
||||||
echo "Rebasing $SECONDARY_BRANCH on top of $PRIMARY_BRANCH"
|
echo "Rebasing $SECONDARY_BRANCH on top of $PRIMARY_BRANCH"
|
||||||
TARGET_BRANCH="${SECONDARY_BRANCH}-rebased-on-top-of-${PRIMARY_BRANCH}"
|
TARGET_BRANCH="${SECONDARY_BRANCH}-rebased-on-top-of-${PRIMARY_BRANCH}"
|
||||||
|
|
||||||
git checkout "${PRIMARY_BRANCH}" || exit 41
|
git checkout ${PRIMARY_BRANCH} || exit 41
|
||||||
git checkout -b "${TARGET_BRANCH}" || exit 42
|
git checkout -b ${TARGET_BRANCH} || exit 42
|
||||||
|
git merge ${SECONDARY_BRANCH} ${FF} \
|
||||||
|
-m "Psycho-rebased branch ${SECONDARY_BRANCH} on top of ${PRIMARY_BRANCH}"
|
||||||
|
|
||||||
if git merge "${SECONDARY_BRANCH}" ${FF} \
|
if [[ $? == 0 ]]; then
|
||||||
-m "Psycho-rebased branch ${SECONDARY_BRANCH} on top of ${PRIMARY_BRANCH}"; then
|
git branch -d ${SECONDARY_BRANCH} || exit 43
|
||||||
git branch -d "${SECONDARY_BRANCH}" || exit 43
|
git branch -m ${TARGET_BRANCH} ${SECONDARY_BRANCH} || exit 44
|
||||||
git branch -m "${TARGET_BRANCH}" "${SECONDARY_BRANCH}" || exit 44
|
|
||||||
else
|
else
|
||||||
echo "Resolve the conflict and run ``${PROGRAM} --continue``."
|
echo "Resolve the conflict and run ``${PROGRAM} --continue``."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ EOF
|
||||||
# personal access token
|
# personal access token
|
||||||
# config name is github-personal-access-token '_' is not allowed in git config
|
# config name is github-personal-access-token '_' is not allowed in git config
|
||||||
|
|
||||||
github_personal_access_token=$(git config --default "$GITHUB_TOKEN" git-extras.github-personal-access-token)
|
github_personal_access_token=$(git config git-extras.github-personal-access-token)
|
||||||
|
|
||||||
test -z "$github_personal_access_token" && abort "GITHUB_TOKEN or git config git-extras.github-personal-access-token required"
|
test -z "$github_personal_access_token" && abort "git config git-extras.github-personal-access-token required"
|
||||||
|
|
||||||
# branch
|
# branch
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ if [ -z "$remote" ]; then
|
||||||
echo 'no upstream found, push to origin as default'
|
echo 'no upstream found, push to origin as default'
|
||||||
remote="origin"
|
remote="origin"
|
||||||
fi
|
fi
|
||||||
[ "$remote" = "." ] && abort "the upstream should be a remote branch."
|
[ "$remote" == "." ] && abort "the upstream should be a remote branch."
|
||||||
|
|
||||||
# make sure it's pushed
|
# make sure it's pushed
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ echo
|
||||||
|
|
||||||
if [ -z "$base" ]
|
if [ -z "$base" ]
|
||||||
then
|
then
|
||||||
base="$(git_extra_default_branch)"
|
base="master"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
body=$(json "$title" "$body" "$branch" "$base")
|
body=$(json "$title" "$body" "$branch" "$base")
|
||||||
|
|
@ -82,4 +82,4 @@ curl \
|
||||||
-H "Accept: application/vnd.github.v3+json" \
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
-H "Authorization: token $github_personal_access_token" \
|
-H "Authorization: token $github_personal_access_token" \
|
||||||
-H "X-GitHub-OTP: $mfa_code" \
|
-H "X-GitHub-OTP: $mfa_code" \
|
||||||
"https://api.github.com/repos/$project/pulls" -d "$body"
|
"https://api.github.com/repos/$project/pulls" -d "$body"
|
||||||
|
|
@ -17,26 +17,26 @@ fi
|
||||||
# Use a temporary index.
|
# Use a temporary index.
|
||||||
index=$(git_extra_mktemp)
|
index=$(git_extra_mktemp)
|
||||||
cleanup() {
|
cleanup() {
|
||||||
rm "$index"
|
rm $index
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
trap cleanup INT
|
trap cleanup 2
|
||||||
|
|
||||||
# Go back in history while parent commits are available.
|
# Go back in history while parent commits are available.
|
||||||
echo "Trying to find a commit the patch applies to..."
|
echo "Trying to find a commit the patch applies to..."
|
||||||
rev=$(git rev-parse HEAD)
|
rev=$(git rev-parse HEAD)
|
||||||
while [ $? = 0 ]
|
while [ $? = 0 ]
|
||||||
do
|
do
|
||||||
GIT_INDEX_FILE=$index git read-tree "$rev"
|
GIT_INDEX_FILE=$index git read-tree $rev
|
||||||
|
|
||||||
# Try to apply the patch.
|
# Try to apply the patch.
|
||||||
GIT_INDEX_FILE=$index git apply --cached "$1" &>/dev/null
|
GIT_INDEX_FILE=$index git apply --cached $1 >/dev/null 2>&1
|
||||||
patch_failed=$?
|
patch_failed=$?
|
||||||
|
|
||||||
# Do it again, but show the error, if the problem is the patch itself.
|
# Do it again, but show the error, if the problem is the patch itself.
|
||||||
if [ $patch_failed = 128 ]
|
if [ $patch_failed = 128 ]
|
||||||
then
|
then
|
||||||
GIT_INDEX_FILE=$index git apply --index --check "$1"
|
GIT_INDEX_FILE=$index git apply --index --check $1
|
||||||
exit $patch_failed
|
exit $patch_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -45,19 +45,19 @@ do
|
||||||
then
|
then
|
||||||
# Manufacture a commit.
|
# Manufacture a commit.
|
||||||
tree=$(GIT_INDEX_FILE=$index git write-tree)
|
tree=$(GIT_INDEX_FILE=$index git write-tree)
|
||||||
commit=$(git commit-tree "$tree" -p "$rev" -m "$1")
|
commit=$(git commit-tree $tree -p $rev -m "$1")
|
||||||
rm "$index"
|
rm $index
|
||||||
|
|
||||||
echo "Patch applied to $(git rev-parse --short "$rev") as $(git rev-parse --short "$commit")"
|
echo "Patch applied to $(git rev-parse --short $rev) as $(git rev-parse --short $commit)"
|
||||||
|
|
||||||
git cherry-pick "$commit"
|
git cherry-pick $commit
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rev=$(git rev-parse --verify -q "$rev^")
|
rev=$(git rev-parse --verify -q $rev^)
|
||||||
done
|
done
|
||||||
|
|
||||||
# No compatible commit found. Restore.
|
# No compatible commit found. Restore.
|
||||||
echo "Failed to find a commit the patch applies to."
|
echo "Failed to find a commit the patch applies to."
|
||||||
rm "$index"
|
rm $index
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,17 @@ set -e
|
||||||
hook() {
|
hook() {
|
||||||
local hook=.git/hooks/$1.sh
|
local hook=.git/hooks/$1.sh
|
||||||
# compat without extname
|
# compat without extname
|
||||||
if test ! -f "$hook"; then
|
if test ! -f $hook; then
|
||||||
hook=.git/hooks/$1
|
hook=.git/hooks/$1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -f "$hook"; then
|
if test -f $hook; then
|
||||||
echo "... $1"
|
echo "... $1"
|
||||||
shift
|
shift
|
||||||
if test -x "$hook"; then
|
if test -x $hook; then
|
||||||
$hook "$@"
|
$hook "$@"
|
||||||
else
|
else
|
||||||
. "$hook" "$@"
|
. $hook "$@"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +119,7 @@ if test $# -gt 0; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
declare -a sign_args
|
declare -a sign_args
|
||||||
if [ "$sign" = true ]; then
|
if [ "$sign" == true ]; then
|
||||||
sign_args=("-s")
|
sign_args=("-s")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Assert there is at least one branch provided
|
# Assert there is at least one branch provided
|
||||||
test -z "$1" && echo "new branch name required." 1>&2 && exit 1
|
test -z $1 && echo "new branch name required." 1>&2 && exit 1
|
||||||
|
|
||||||
if [ -z "$2" ]; then
|
if [ -z $2 ]; then
|
||||||
new_branch="$1"
|
new_branch="$1"
|
||||||
old_branch="$(git symbolic-ref --short -q HEAD)"
|
old_branch="$(git symbolic-ref --short -q HEAD)"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Usage function
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: git rename-file [OPTIONS] <source> <destination>
|
|
||||||
|
|
||||||
Description:
|
|
||||||
Rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity.
|
|
||||||
It combines the functionality of the "mv" command and "git mv". This is particularly useful for renaming files or directories
|
|
||||||
to change only their case, which might not be detected by Git on case-insensitive filesystems.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-h, --help Show this help message and exit.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
git rename-file old_filename new_filename
|
|
||||||
git rename-file old_directory new_directory
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check for help option
|
|
||||||
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for correct number of arguments
|
|
||||||
if [ "$#" -ne 2 ]; then
|
|
||||||
echo "Error: Incorrect number of arguments."
|
|
||||||
echo ""
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Assign variables
|
|
||||||
SOURCE="$1"
|
|
||||||
DESTINATION="$2"
|
|
||||||
TEMP_NAME="${SOURCE}.temp"
|
|
||||||
|
|
||||||
# Function to check if a file or directory exists in a case-sensitive manner
|
|
||||||
check_case_sensitive_exists() {
|
|
||||||
local path="$1"
|
|
||||||
local dir
|
|
||||||
local base
|
|
||||||
|
|
||||||
dir=$(dirname "$path")
|
|
||||||
base=$(basename "$path")
|
|
||||||
|
|
||||||
if [ -e "$dir" ]; then
|
|
||||||
if (cd "$dir" && find . -maxdepth 1 -name "$base" | grep -q "$base"); then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if source exists and is under version control
|
|
||||||
if ! check_case_sensitive_exists "$SOURCE"; then
|
|
||||||
echo "Error: Source '$SOURCE' does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! git ls-files --error-unmatch "$SOURCE" > /dev/null 2>&1; then
|
|
||||||
echo "Error: Source '$SOURCE' is not under version control. If file or directory is new, it must at least be staged."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if destination already exists
|
|
||||||
if check_case_sensitive_exists "$DESTINATION"; then
|
|
||||||
echo "Error: Destination '$DESTINATION' already exists."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if the destination directory exists
|
|
||||||
DEST_DIR=$(dirname "$DESTINATION")
|
|
||||||
if ! check_case_sensitive_exists "$DEST_DIR"; then
|
|
||||||
echo "Error: Destination directory '$DEST_DIR' does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create a rollback function
|
|
||||||
rollback() {
|
|
||||||
echo "Rolling back changes..."
|
|
||||||
if [ -e "$TEMP_NAME" ]; then
|
|
||||||
git mv -f "$TEMP_NAME" "$SOURCE"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trap errors to trigger rollback
|
|
||||||
trap 'rollback' ERR
|
|
||||||
|
|
||||||
# Move the file to a temporary name within the Git repository
|
|
||||||
git mv "$SOURCE" "$TEMP_NAME"
|
|
||||||
|
|
||||||
# Move the temporary file to the desired destination
|
|
||||||
git mv "$TEMP_NAME" "$DESTINATION"
|
|
||||||
|
|
||||||
echo "Successfully renamed '$SOURCE' to '$DESTINATION'."
|
|
||||||
|
|
@ -5,8 +5,8 @@ set -euo pipefail
|
||||||
old=$1
|
old=$1
|
||||||
new=$2
|
new=$2
|
||||||
|
|
||||||
test -z "$old" && echo "old remote name required." 1>&2 && exit 1
|
test -z $old && echo "old remote name required." 1>&2 && exit 1
|
||||||
test -z "$new" && echo "new remote name required." 1>&2 && exit 1
|
test -z $new && echo "new remote name required." 1>&2 && exit 1
|
||||||
|
|
||||||
if ! git config --get "remote.$old.fetch" > /dev/null; then
|
if ! git config --get "remote.$old.fetch" > /dev/null; then
|
||||||
echo "remote $old doesn't exist"
|
echo "remote $old doesn't exist"
|
||||||
|
|
@ -14,7 +14,7 @@ if ! git config --get "remote.$old.fetch" > /dev/null; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if git config --get "remote.$new.fetch" > /dev/null; then
|
if git config --get "remote.$new.fetch" > /dev/null; then
|
||||||
git remote remove "$new"
|
git remote remove $new
|
||||||
fi
|
fi
|
||||||
git remote rename "$old $new"
|
git remote rename $old $new
|
||||||
git remote -v
|
git remote -v
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
old=$1
|
old=$1
|
||||||
new=$2
|
new=$2
|
||||||
|
|
||||||
test -z "$old" && echo "old tag name required." 1>&2 && exit 1
|
test -z $old && echo "old tag name required." 1>&2 && exit 1
|
||||||
test -z "$new" && echo "new tag name required." 1>&2 && exit 1
|
test -z $new && echo "new tag name required." 1>&2 && exit 1
|
||||||
|
|
||||||
git tag "$new" "$old"
|
git tag $new $old
|
||||||
git tag -d "$old"
|
git tag -d $old
|
||||||
git push origin "$new"
|
git push origin $new
|
||||||
git push origin ":refs/tags/$old"
|
git push origin :refs/tags/$old
|
||||||
|
|
|
||||||
82
bin/git-repl
82
bin/git-repl
|
|
@ -1,99 +1,43 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
shopt -s extglob
|
|
||||||
|
|
||||||
git version
|
git version
|
||||||
echo "git-extras version ""$(git-extras -v)"
|
echo "git-extras version ""$(git-extras -v)"
|
||||||
echo "Type 'ls' to ls files below current directory; '!command' to execute any command or just 'subcommand' to execute any git subcommand; 'quit', 'exit', 'q', ^D, or ^C to exit the git repl."
|
echo "type 'ls' to ls files below current directory, '!command' to execute any command or just 'subcommand' to execute any git subcommand"
|
||||||
|
|
||||||
HISTIGNORE=${HISTIGNORE:-+([[:space:]])}
|
|
||||||
HISTCONTROL=${HISTCONTROL:-ignoredups}
|
|
||||||
use_local_history=$(git config --get --default 'false' git-extras.repl.use-local-history)
|
|
||||||
if [[ "$use_local_history" == "true" ]]; then
|
|
||||||
HISTFILE="$(git rev-parse --show-toplevel)/.git_extras_repl_history"
|
|
||||||
else
|
|
||||||
HISTFILE=${XDG_STATE_HOME:-$HOME/.local/state}/git_extras_repl_history
|
|
||||||
fi
|
|
||||||
|
|
||||||
# file doesn't exist, is empty, or contains only whitespace
|
|
||||||
if [[ ! -f "$HISTFILE" ]] || [[ ! -s "$HISTFILE" ]] || ! grep -q '[^[:space:]]' "$HISTFILE"; then
|
|
||||||
# `history -r` .... `history -a` are not happy with an empty initial file in bash 3.2.57, which is what MacOS 26 ships with
|
|
||||||
echo '!echo welcome to git-repl!' >> "$HISTFILE"
|
|
||||||
fi
|
|
||||||
history -r
|
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Current branch
|
# Current branch
|
||||||
cur=$(git symbolic-ref HEAD 2> /dev/null | cut -d/ -f3-)
|
cur=`git symbolic-ref HEAD 2> /dev/null | cut -d/ -f3-`
|
||||||
|
|
||||||
# Prompt
|
# Prompt
|
||||||
if test -n "$cur"; then
|
if test -n "$cur"; then
|
||||||
cur_string=" ($cur)"
|
prompt="git ($cur)> "
|
||||||
else
|
else
|
||||||
cur_string=""
|
prompt="git> "
|
||||||
fi
|
|
||||||
if test -n "$exit_status" && test "$exit_status" -ne 0; then
|
|
||||||
es_string=$' \e[31m['"$exit_status"$']\e[0m'
|
|
||||||
else
|
|
||||||
es_string=""
|
|
||||||
fi
|
|
||||||
prompt_character=$(git config --get --default '>' git-extras.repl.prompt-character)
|
|
||||||
|
|
||||||
prefix=$(git config --get --default 'git' git-extras.repl.prefix)
|
|
||||||
|
|
||||||
show_project_name=$(git config --get --default 'false' git-extras.repl.show-project-name)
|
|
||||||
if [[ "$show_project_name" == "true" ]]; then
|
|
||||||
project_name=" $(basename "$(git rev-parse --show-toplevel)" .git)"
|
|
||||||
else
|
|
||||||
project_name=""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prompt_base="$prefix$project_name$cur_string$es_string$prompt_character"
|
# Readline
|
||||||
prompt_base_stripped=$(echo "$prompt_base" | awk '{$1=$1};1')
|
read -e -r -p "$prompt" cmd
|
||||||
prompt="$prompt_base_stripped "
|
|
||||||
|
|
||||||
# Use arguments as a command if any are provided.
|
# EOF
|
||||||
if [ $# -ne 0 ]; then
|
test $? -ne 0 && break
|
||||||
cmd=$*
|
|
||||||
set --
|
|
||||||
echo "$prompt" "$cmd" # It is as though you had entered a command.
|
|
||||||
else
|
|
||||||
# Readline
|
|
||||||
read -e -r -p "$prompt" cmd
|
|
||||||
# Check for EOF, and end the program if so (handles ^D).
|
|
||||||
test $? -ne 0 && break
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add command to history if it is not all whitespace
|
# History
|
||||||
if [[ ! "$cmd" =~ ^[[:space:]]*$ ]]; then
|
history -s "$cmd"
|
||||||
history -s "$cmd"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Built-in commands
|
# Built-in commands
|
||||||
case $cmd in
|
case $cmd in
|
||||||
ls) cmd=ls-files;;
|
ls) cmd=ls-files;;
|
||||||
"")
|
"") continue;;
|
||||||
on_enter_cmd=$(git config --get --default '' git-extras.repl.on-enter-command)
|
quit|exit) break;;
|
||||||
if test -n "$on_enter_cmd"; then
|
|
||||||
cmd="$on_enter_cmd"
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
quit|exit|q) break;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
history -a
|
|
||||||
|
|
||||||
if [[ $cmd == !* ]]; then
|
if [[ $cmd == !* ]]; then
|
||||||
# shellcheck disable=SC2086
|
eval ${cmd:1}
|
||||||
eval ${cmd:1}
|
|
||||||
elif [[ $cmd == git* ]]; then
|
elif [[ $cmd == git* ]]; then
|
||||||
# shellcheck disable=SC2086
|
|
||||||
eval $cmd
|
eval $cmd
|
||||||
else
|
else
|
||||||
eval git "$cmd"
|
eval git "$cmd"
|
||||||
fi
|
fi
|
||||||
exit_status=$?
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ file="$1"
|
||||||
commit="$2"
|
commit="$2"
|
||||||
|
|
||||||
if [[ -f $file ]]; then
|
if [[ -f $file ]]; then
|
||||||
git rm --cached -q -f -- "$file"
|
git rm --cached -q -f -- $file
|
||||||
if [[ -z $commit ]]; then
|
if [[ -z $commit ]]; then
|
||||||
git checkout HEAD -- "$file"
|
git checkout HEAD -- $file
|
||||||
echo "Reset '$1' to HEAD"
|
echo "Reset '$1' to HEAD"
|
||||||
else
|
else
|
||||||
git checkout "$commit" -- "$file"
|
git checkout $commit -- $file
|
||||||
echo "Reset '$1' to $commit"
|
echo "Reset '$1' to $commit"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "File '$1' not found in $PWD"
|
echo "File '$1' not found in `pwd`"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,7 @@ git_root() {
|
||||||
|
|
||||||
# get the relative path of current path according to root of repo
|
# get the relative path of current path according to root of repo
|
||||||
git_root_relative() {
|
git_root_relative() {
|
||||||
rel=$(git rev-parse --show-prefix)
|
git rev-parse --show-prefix
|
||||||
if [ -z "$rel" ]; then
|
|
||||||
# git rev-parse --show-prefix will output empty string when we are in the root dir
|
|
||||||
echo "."
|
|
||||||
else
|
|
||||||
echo "$rel"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if test $# -eq 0; then
|
if test $# -eq 0; then
|
||||||
|
|
|
||||||
171
bin/git-scp
171
bin/git-scp
|
|
@ -18,7 +18,7 @@ function _test_git_scp()
|
||||||
function set_remote()
|
function set_remote()
|
||||||
{
|
{
|
||||||
remote=$1
|
remote=$1
|
||||||
if [ "$(git remote | grep -c -- "^$remote$")" -eq 0 ]
|
if [ $(git remote | grep -c -- ^$remote$) -eq 0 ]
|
||||||
then
|
then
|
||||||
COLOR_RED
|
COLOR_RED
|
||||||
echo "Remote $remote does not exist in your git config"
|
echo "Remote $remote does not exist in your git config"
|
||||||
|
|
@ -39,9 +39,8 @@ function php_lint()
|
||||||
test ! -f "$i" && continue
|
test ! -f "$i" && continue
|
||||||
case "$i" in
|
case "$i" in
|
||||||
*\.php|*\.phtml)
|
*\.php|*\.phtml)
|
||||||
if ! php -l "$i" > /dev/null; then
|
php -l "$i" > /dev/null
|
||||||
error_count[${#error_count[@]}]="$i"
|
[ $? -gt 0 ] && error_count[${#error_count[@]}]="$i"
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
@ -59,17 +58,17 @@ function php_lint()
|
||||||
|
|
||||||
function _dos2unix()
|
function _dos2unix()
|
||||||
{
|
{
|
||||||
command -v dos2unix > /dev/null && dos2unix "$@"
|
command -v dos2unix > /dev/null && dos2unix $@
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function _sanitize()
|
function _sanitize()
|
||||||
{
|
{
|
||||||
git config --get-all extras.scp.sanitize | while read -r i
|
git config --get-all extras.scp.sanitize | while read i
|
||||||
do
|
do
|
||||||
case $i in
|
case $i in
|
||||||
php_lint) php_lint "$@";; # git config --global --add extras.scp.sanitize php_lint
|
php_lint) php_lint $@;; # git config --global --add extras.scp.sanitize php_lint
|
||||||
dos2unix) _dos2unix "$@";; # git config --global --add extras.scp.sanitize dos2unix
|
dos2unix) _dos2unix $@;; # git config --global --add extras.scp.sanitize dos2unix
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
return $?
|
return $?
|
||||||
|
|
@ -77,26 +76,14 @@ function _sanitize()
|
||||||
|
|
||||||
function scp_and_stage
|
function scp_and_stage
|
||||||
{
|
{
|
||||||
local verbose=0 interactive=0 dry_run=0
|
set_remote $1
|
||||||
while :
|
|
||||||
do
|
|
||||||
case "$1" in
|
|
||||||
-v|--verbose) verbose=1; shift;;
|
|
||||||
-i|--interactive) verbose=1; interactive=1; shift;;
|
|
||||||
-n|--dry-run) verbose=1; dry_run=1; shift;;
|
|
||||||
*) break;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
set_remote "$1"
|
|
||||||
shift
|
shift
|
||||||
|
|
||||||
local refhead
|
local refhead="$(git rev-parse --quiet --verify $1)"
|
||||||
refhead="$(git rev-parse --quiet --verify "$1")"
|
|
||||||
if [ -n "$refhead" ]
|
if [ -n "$refhead" ]
|
||||||
then
|
then
|
||||||
shift
|
shift
|
||||||
[ "$(git branch --contains "$refhead" | grep -c '\*')" -eq 0 ] &&
|
[ $(git branch --contains "$refhead" | grep -c '\*') -eq 0 ] &&
|
||||||
_error "refhead provided is not part of current branch"
|
_error "refhead provided is not part of current branch"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -105,117 +92,46 @@ function scp_and_stage
|
||||||
list=$(git ls-files "$@")" "$(git ls-files -o "$@")
|
list=$(git ls-files "$@")" "$(git ls-files -o "$@")
|
||||||
elif [ -n "$refhead" ]
|
elif [ -n "$refhead" ]
|
||||||
then
|
then
|
||||||
[ "$verbose" -eq 1 ] && git --no-pager diff --stat "$refhead"
|
git diff --stat $refhead
|
||||||
list=$(git diff "$refhead" --name-only)
|
list=$(git diff $refhead --name-only)
|
||||||
else
|
else
|
||||||
[ "$verbose" -eq 1 ] && git --no-pager diff
|
git diff
|
||||||
list=$(git diff --name-only)
|
list=$(git diff --name-only)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
deleted=$(for i in $list; do [ -f "$i" ] || echo "$i"; done)
|
deleted=$(for i in $list; do [ -f $i ] || echo $i; done)
|
||||||
list=$(for i in $list; do [ -f "$i" ] && echo "$i"; done)
|
list=$(for i in $list; do [ -f $i ] && echo $i; done)
|
||||||
|
|
||||||
if [ "$interactive" -eq 1 ] && [ "$dry_run" -eq 0 ] && { [ -n "$list" ] || [ -n "$deleted" ]; }
|
|
||||||
then
|
|
||||||
local reply
|
|
||||||
read -r -p "Proceed with sync to $remote? [y/N] " reply
|
|
||||||
case "$reply" in
|
|
||||||
y|Y|yes|YES) ;;
|
|
||||||
*) _info "Aborted, nothing synced."; exit 0;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
local status=0
|
|
||||||
|
|
||||||
if [ -n "$list" ]
|
if [ -n "$list" ]
|
||||||
then
|
then
|
||||||
local _TMP=${0///}
|
local _TMP=${0///}
|
||||||
# shellcheck disable=SC2086
|
echo "$list" > $_TMP &&
|
||||||
echo "$list" > "$_TMP"
|
_sanitize $list &&
|
||||||
if [ "$dry_run" -eq 1 ] || _sanitize $list
|
_info Pushing to $remote \($(git config remote.$remote.url)\) &&
|
||||||
then
|
rsync -rlDv --files-from=$_TMP ./ "$(git config remote.$remote.url)/" &&
|
||||||
_info "Pushing to $remote ($(git config "remote.$remote.url"))"
|
git add --force $list &&
|
||||||
if [ "$dry_run" -eq 1 ]
|
rm $_TMP
|
||||||
then
|
|
||||||
rsync -rlDvn --files-from="$_TMP" ./ "$(git config "remote.$remote.url")/"
|
|
||||||
else
|
|
||||||
rsync -rlDv --files-from="$_TMP" ./ "$(git config "remote.$remote.url")/" &&
|
|
||||||
git add --force $list
|
|
||||||
fi
|
|
||||||
status=$?
|
|
||||||
else
|
|
||||||
status=1
|
|
||||||
fi
|
|
||||||
rm "$_TMP"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
deleted=$(for i in $deleted; do echo "$(git config "remote.$remote.url" | cut -d: -f2)/$i"; done)
|
deleted=$(for i in $deleted; do echo $(git config remote.$remote.url | cut -d: -f2)/$i; done)
|
||||||
|
|
||||||
if [ -n "$deleted" ]
|
[ -n "$deleted" ] &&
|
||||||
then
|
COLOR_RED &&
|
||||||
COLOR_RED
|
echo Deleted remote files &&
|
||||||
echo Deleted remote files
|
ssh $(git config remote.$remote.url | cut -d: -f1) -t "rm $deleted" &&
|
||||||
if [ "$dry_run" -eq 1 ]
|
echo "$deleted"
|
||||||
then
|
COLOR_RESET
|
||||||
echo "$deleted"
|
|
||||||
else
|
|
||||||
if ssh "$(git config "remote.$remote.url" | cut -d: -f1)" -t "rm $deleted"
|
|
||||||
then
|
|
||||||
echo "$deleted"
|
|
||||||
else
|
|
||||||
status=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
COLOR_RESET
|
|
||||||
fi
|
|
||||||
|
|
||||||
return "$status"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function reverse_scp()
|
function reverse_scp()
|
||||||
{
|
{
|
||||||
local verbose=0 interactive=0 dry_run=0
|
set_remote $1
|
||||||
while :
|
|
||||||
do
|
|
||||||
case "$1" in
|
|
||||||
-v|--verbose) verbose=1; shift;;
|
|
||||||
-i|--interactive) verbose=1; interactive=1; shift;;
|
|
||||||
-n|--dry-run) verbose=1; dry_run=1; shift;;
|
|
||||||
*) break;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
set_remote "$1"
|
|
||||||
shift
|
shift
|
||||||
|
|
||||||
local _TMP=${0///}
|
local _TMP=${0///}
|
||||||
echo "$@" > "$_TMP"
|
echo $@ > $_TMP &&
|
||||||
|
rsync -rlDv --files-from=$_TMP "$(git config remote.$remote.url)/" ./ &&
|
||||||
local status=0
|
rm $_TMP
|
||||||
if [ "$verbose" -eq 1 ]
|
|
||||||
then
|
|
||||||
rsync -rlDvn --files-from="$_TMP" "$(git config "remote.$remote.url")/" ./
|
|
||||||
status=$?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$dry_run" -eq 1 ]
|
|
||||||
then
|
|
||||||
rm "$_TMP"
|
|
||||||
return "$status"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$interactive" -eq 1 ]
|
|
||||||
then
|
|
||||||
local reply
|
|
||||||
read -r -p "Proceed with copy from $remote? [y/N] " reply
|
|
||||||
case "$reply" in
|
|
||||||
y|Y|yes|YES) ;;
|
|
||||||
*) _info "Aborted, nothing copied."; rm "$_TMP"; exit 0;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
rsync -rlDv --files-from="$_TMP" "$(git config "remote.$remote.url")/" ./ &&
|
|
||||||
rm "$_TMP"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _info()
|
function _info()
|
||||||
|
|
@ -229,18 +145,13 @@ function _usage()
|
||||||
{
|
{
|
||||||
echo "Usage:
|
echo "Usage:
|
||||||
git scp -h|help|?
|
git scp -h|help|?
|
||||||
git scp [options] <remote> [ref|file..] # scp and stage your files to specified remote
|
git scp <remote> [ref|file..] # scp and stage your files to specified remote
|
||||||
git scp [options] <remote> [<ref>] # show diff relative to <ref> and upload unstaged files to <remote>
|
git scp <remote> [<ref>] # show diff relative to <ref> and upload unstaged files to <remote>
|
||||||
git rscp [options] <remote> [<file|directory>] # copy <remote> files to current working directory
|
git rscp <remote> [<file|directory>] # copy <remote> files to current working directory
|
||||||
|
|
||||||
OPTIONS:
|
|
||||||
-v, --verbose print what will be synced before syncing
|
|
||||||
-i, --interactive prompt for confirmation before syncing (implies --verbose)
|
|
||||||
-n, --dry-run show what would be synced, change nothing (implies --verbose; no staging, no remote writes/deletes)
|
|
||||||
"
|
"
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
-v|verbose|--verbose) grep -A100 '^#* OPTIONS #*$' "$0" ;;
|
-v|verbose|--verbose) grep -A100 '^#* OPTIONS #*$' $0;;
|
||||||
esac
|
esac
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
@ -250,18 +161,18 @@ function _error()
|
||||||
[ $# -eq 0 ] && _usage && exit 0
|
[ $# -eq 0 ] && _usage && exit 0
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "ERROR: $*"
|
echo ERROR: "$@"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
### OPTIONS ###
|
### OPTIONS ###
|
||||||
case $(basename "$0") in
|
case $(basename $0) in
|
||||||
git-scp)
|
git-scp)
|
||||||
case $1 in
|
case $1 in
|
||||||
''|-h|'?'|help|--help) shift; _test_git_scp; _usage "$@";;
|
''|-h|'?'|help|--help) shift; _test_git_scp; _usage $@;;
|
||||||
*) scp_and_stage "$@";;
|
*) scp_and_stage $@;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
git-rscp) reverse_scp "$@";;
|
git-rscp) reverse_scp $@;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
12
bin/git-sed
12
bin/git-sed
|
|
@ -17,7 +17,7 @@ do_commit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pathspec=
|
pathspec=
|
||||||
while [ "$1" != "" ]; do
|
while [ "X$1" != "X" ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-c|--commit)
|
-c|--commit)
|
||||||
if git status --porcelain | grep .; then
|
if git status --porcelain | grep .; then
|
||||||
|
|
@ -33,7 +33,7 @@ actual command:
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
-f|--flags)
|
-f|--flags)
|
||||||
if [ "$2" = "" ]; then
|
if [ "X$2" = "X" ]; then
|
||||||
usage
|
usage
|
||||||
echo "missing argument for $1"
|
echo "missing argument for $1"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -55,11 +55,11 @@ actual command:
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if [ "$search" = "" ]; then
|
if [ "X$search" = "X" ]; then
|
||||||
search="$1"
|
search="$1"
|
||||||
elif [ "$replacement" = "" ]; then
|
elif [ "X$replacement" = "X" ]; then
|
||||||
replacement="$1"
|
replacement="$1"
|
||||||
elif [ "$flags" = "" ]; then
|
elif [ "X$flags" = "X" ]; then
|
||||||
flags="$1"
|
flags="$1"
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
|
|
@ -79,7 +79,7 @@ case "$all" in
|
||||||
escaped="${escaped//[/\\[}"
|
escaped="${escaped//[/\\[}"
|
||||||
sep="$(printf '%s' "$ascii" | tr -d "$escaped")"
|
sep="$(printf '%s' "$ascii" | tr -d "$escaped")"
|
||||||
sep="$(printf %.1s "$sep")"
|
sep="$(printf %.1s "$sep")"
|
||||||
if [ "$sep" = "" ] ; then
|
if [ "X$sep" = "X" ] ; then
|
||||||
echo 'could not find an unused character for sed separator character'
|
echo 'could not find an unused character for sed separator character'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
COMMIT_MESSAGE='Initial commit'
|
COMMIT_MESSAGE='Initial commit'
|
||||||
|
|
||||||
if [ "$1" = "-m" ]; then
|
if [ "$1" == "-m" ]; then
|
||||||
COMMIT_MESSAGE=$2
|
COMMIT_MESSAGE=$2
|
||||||
shift; shift
|
shift; shift
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
git branch --no-color --merged | grep -v "\*" | grep -v "$(git_extra_default_branch)" | tr -d ' '
|
git branch --no-color --merged | grep -v "\*" | grep -v $(git_extra_default_branch) | tr -d ' '
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
git branch --no-color --no-merged | grep -v "\*" | grep -v "$(git_extra_default_branch)" | tr -d ' '
|
git branch --no-color --no-merged | grep -v "\*" | grep -v $(git_extra_default_branch) | tr -d ' '
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ EOF
|
||||||
|
|
||||||
error() {
|
error() {
|
||||||
if [[ -n "$1" ]]; then
|
if [[ -n "$1" ]]; then
|
||||||
echo "error: $1" >&2
|
local msg=$( echo "error: $1" )
|
||||||
|
echo -e "${msg}" >&2
|
||||||
fi
|
fi
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -33,7 +34,7 @@ stamp() {
|
||||||
local commit_msg=$( git log -1 --pretty=%B )
|
local commit_msg=$( git log -1 --pretty=%B )
|
||||||
local stamp_msg
|
local stamp_msg
|
||||||
[[ -n "${MSG}" ]] && stamp_msg="${ID} ${MSG}" || stamp_msg="${ID}"
|
[[ -n "${MSG}" ]] && stamp_msg="${ID} ${MSG}" || stamp_msg="${ID}"
|
||||||
|
|
||||||
if ${REPLACE}; then
|
if ${REPLACE}; then
|
||||||
# remove previous stamps with same ID from the commit message
|
# remove previous stamps with same ID from the commit message
|
||||||
commit_msg=$(
|
commit_msg=$(
|
||||||
|
|
@ -70,9 +71,9 @@ parse_options() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
ID="$1"
|
ID="$1"
|
||||||
MSG="${*:2}"
|
MSG="${@:2}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOS
|
cat <<EOS
|
||||||
Usage:
|
Usage:
|
||||||
git standup [-a <author name>] [-w <weekstart-weekend>|-d <days-ago>] [-m <max-dir-depth>] [-D date-format] [-L] [-h] [-f] [-B] [-n <number-of-commits] [-F <gpg|authordate>]
|
git standup [-a <author name>] [-w <weekstart-weekend>] [-d <days-ago>] [-m <max-dir-depth>] [-g] [-h] [-f] [-B] [-n <number-of-commits]
|
||||||
|
|
||||||
-a - Specify author to restrict search to, default to current git user.
|
-a - Specify author to restrict search to, default to current git user.
|
||||||
Use "-a all" if you don't want the restriction.
|
Use "-a all" if you don't want the restriction.
|
||||||
|
|
@ -15,11 +15,10 @@ usage() {
|
||||||
-d - Specify the number of days back to include
|
-d - Specify the number of days back to include
|
||||||
-D - Specify the date format for "git log" (default: relative)
|
-D - Specify the date format for "git log" (default: relative)
|
||||||
-h - Display this help screen
|
-h - Display this help screen
|
||||||
|
-g - Show if commit is GPG signed (G) or not (N)
|
||||||
-f - Fetch the latest commits beforehand
|
-f - Fetch the latest commits beforehand
|
||||||
-B - Display the commits in branch groups
|
-B - Display the commits in branch groups
|
||||||
-n - Limit the number of commits displayed per group
|
-n - Limit the number of commits displayed per group
|
||||||
-F gpg - Show if commit is GPG signed (G) or not (N)
|
|
||||||
-F authordate - Print author date instead of commit date
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
git standup -a "John Doe" -w "MON-FRI" -m 3
|
git standup -a "John Doe" -w "MON-FRI" -m 3
|
||||||
|
|
@ -35,7 +34,7 @@ in_git_repo=$?
|
||||||
|
|
||||||
# Use colors, but only if connected to a terminal, and that terminal
|
# Use colors, but only if connected to a terminal, and that terminal
|
||||||
# supports them.
|
# supports them.
|
||||||
if command -v tput &>/dev/null; then
|
if which tput >/dev/null 2>&1; then
|
||||||
ncolors=$(tput colors)
|
ncolors=$(tput colors)
|
||||||
fi
|
fi
|
||||||
if [[ -t 1 ]] && [[ -n "$ncolors" ]] && [[ "$ncolors" -ge 8 ]] ; then
|
if [[ -t 1 ]] && [[ -n "$ncolors" ]] && [[ "$ncolors" -ge 8 ]] ; then
|
||||||
|
|
@ -64,11 +63,7 @@ fi
|
||||||
# which may fail on systems lacking tput or terminfo
|
# which may fail on systems lacking tput or terminfo
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
RANGE_SPECIFIED=
|
while getopts "hgfBd:a:w:m:D:n:L" opt; do
|
||||||
COMMIT_DATE_FORMAT=%cd
|
|
||||||
USE_GPG_FORMAT=no
|
|
||||||
|
|
||||||
while getopts "hgfF:Bd:a:w:m:D:n:L" opt; do
|
|
||||||
case $opt in
|
case $opt in
|
||||||
h)
|
h)
|
||||||
usage
|
usage
|
||||||
|
|
@ -82,8 +77,7 @@ while getopts "hgfF:Bd:a:w:m:D:n:L" opt; do
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
d)
|
d)
|
||||||
test -n "$RANGE_SPECIFIED" && warn "-d option is conflict with -w"
|
test -n "$SINCE" && warn "-d option is conflict with -w"
|
||||||
RANGE_SPECIFIED=yes
|
|
||||||
if [ "$OPTARG" -lt 1 ]; then
|
if [ "$OPTARG" -lt 1 ]; then
|
||||||
>&2 echo "Specify days less than one is invalid"
|
>&2 echo "Specify days less than one is invalid"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -91,11 +85,10 @@ while getopts "hgfF:Bd:a:w:m:D:n:L" opt; do
|
||||||
SINCE="$OPTARG days ago"
|
SINCE="$OPTARG days ago"
|
||||||
;;
|
;;
|
||||||
w)
|
w)
|
||||||
if [ -n "$RANGE_SPECIFIED" ]; then
|
if [ -n "$SINCE" ]; then
|
||||||
warn "-w option is conflict with -d"
|
warn "-w option is conflict with -d"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
RANGE_SPECIFIED=yes
|
|
||||||
|
|
||||||
week_range=${OPTARG}
|
week_range=${OPTARG}
|
||||||
week_start="${week_range%%-*}"
|
week_start="${week_range%%-*}"
|
||||||
|
|
@ -127,8 +120,7 @@ while getopts "hgfF:Bd:a:w:m:D:n:L" opt; do
|
||||||
GIT_DATE_FORMAT=${OPTARG}
|
GIT_DATE_FORMAT=${OPTARG}
|
||||||
;;
|
;;
|
||||||
g)
|
g)
|
||||||
warn "-g option is deprecated, use '-F gpg' instead"
|
GIT_PRETTY_FORMAT="%C(yellow)gpg: %G?%Creset"
|
||||||
USE_GPG_FORMAT=yes
|
|
||||||
;;
|
;;
|
||||||
B)
|
B)
|
||||||
GROUP_BY_BRANCHES=true
|
GROUP_BY_BRANCHES=true
|
||||||
|
|
@ -136,21 +128,6 @@ while getopts "hgfF:Bd:a:w:m:D:n:L" opt; do
|
||||||
n)
|
n)
|
||||||
MAX_COMMIT_NUM=${OPTARG}
|
MAX_COMMIT_NUM=${OPTARG}
|
||||||
;;
|
;;
|
||||||
F)
|
|
||||||
case $OPTARG in
|
|
||||||
gpg)
|
|
||||||
USE_GPG_FORMAT=yes
|
|
||||||
;;
|
|
||||||
authordate)
|
|
||||||
COMMIT_DATE_FORMAT=%ad
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
warn "Invalid argument for -F: $OPTARG"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
\?)
|
\?)
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -171,34 +148,13 @@ if [[ $# -gt 0 ]]; then
|
||||||
UNTIL=$3
|
UNTIL=$3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AUTHOR=${AUTHOR:="$(git config user.name || echo '')"}
|
AUTHOR=${AUTHOR:="$(git config user.name)"}
|
||||||
if [ -z "${AUTHOR}" ]; then
|
SINCE=${SINCE:=yesterday}
|
||||||
warn "please configure an author with 'git config user.name' or specify an author via '-a'"
|
UNTIL=${UNTIL:=today}
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
FETCH_LAST_COMMIT=${FETCH_LAST_COMMIT:=false}
|
FETCH_LAST_COMMIT=${FETCH_LAST_COMMIT:=false}
|
||||||
MAXDEPTH=${MAXDEPTH:=2}
|
MAXDEPTH=${MAXDEPTH:=2}
|
||||||
GIT_PRETTY_FORMAT="%Cred%h%Creset - %s %Cgreen(${COMMIT_DATE_FORMAT}) %C(bold blue)<%an>%Creset"
|
GIT_PRETTY_FORMAT="%Cred%h%Creset - %s %Cgreen(%cd) %C(bold blue)<%an>%Creset $GIT_PRETTY_FORMAT"
|
||||||
GIT_DATE_FORMAT=${GIT_DATE_FORMAT:=relative}
|
GIT_DATE_FORMAT=${GIT_DATE_FORMAT:=relative}
|
||||||
if [[ "$USE_GPG_FORMAT" == 'yes' ]]; then
|
|
||||||
GIT_PRETTY_FORMAT="$GIT_PRETTY_FORMAT %C(yellow)gpg: %G?%Creset"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle config of implicit week
|
|
||||||
IMPLICIT_WEEK=$(git config --get git-extras.standup.implicit-week || echo '')
|
|
||||||
if [[ -z "$RANGE_SPECIFIED" ]] && [[ -n "${IMPLICIT_WEEK}" ]]; then
|
|
||||||
week_start=${IMPLICIT_WEEK%%-*}
|
|
||||||
week_end=${IMPLICIT_WEEK##*-}
|
|
||||||
shopt -s nocasematch
|
|
||||||
if [[ "$week_start" == "$(LC_ALL=C date +%a)" ]]; then
|
|
||||||
SINCE="last $week_end"
|
|
||||||
fi
|
|
||||||
UNTIL=today
|
|
||||||
else
|
|
||||||
SINCE=${SINCE:=yesterday}
|
|
||||||
UNTIL=${UNTIL:=today}
|
|
||||||
fi
|
|
||||||
|
|
||||||
GIT_LOG_COMMAND="git --no-pager log \
|
GIT_LOG_COMMAND="git --no-pager log \
|
||||||
--no-merges
|
--no-merges
|
||||||
|
|
@ -210,7 +166,7 @@ GIT_LOG_COMMAND="git --no-pager log \
|
||||||
--color=$COLOR
|
--color=$COLOR
|
||||||
--pretty=format:'$GIT_PRETTY_FORMAT'
|
--pretty=format:'$GIT_PRETTY_FORMAT'
|
||||||
--date='$GIT_DATE_FORMAT'"
|
--date='$GIT_DATE_FORMAT'"
|
||||||
if [[ -n "$MAX_COMMIT_NUM" ]]; then
|
if [[ ! -z "$MAX_COMMIT_NUM" ]]; then
|
||||||
GIT_LOG_COMMAND="$GIT_LOG_COMMAND --max-count=$MAX_COMMIT_NUM"
|
GIT_LOG_COMMAND="$GIT_LOG_COMMAND --max-count=$MAX_COMMIT_NUM"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -221,13 +177,13 @@ git_output() {
|
||||||
for branch in $branches; do
|
for branch in $branches; do
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
if output=$(eval $GIT_LOG_COMMAND "$branch"); then
|
if output=$(eval $GIT_LOG_COMMAND "$branch"); then
|
||||||
if [[ -n "$output" ]] ; then
|
if [[ ! -z "$output" ]] ; then
|
||||||
echo "${GREEN}${branch}${NORMAL}"
|
echo "${GREEN}${branch}${NORMAL}"
|
||||||
echo "$output"
|
echo "$output"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
# TODO optimize:return if the latest commit of a branch is earlier than the 'since' day
|
# TODO optimize:return if the latest commit of a branch is eariler than the 'since' day
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
|
|
@ -240,7 +196,6 @@ if [[ $in_git_repo != 0 ]]; then
|
||||||
## Set delimiter to newline for the loop
|
## Set delimiter to newline for the loop
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
## Recursively search for git repositories
|
## Recursively search for git repositories
|
||||||
# shellcheck disable=SC2086
|
|
||||||
PROJECT_DIRS=$(find $INCLUDE_LINKS . -maxdepth "$MAXDEPTH" -mindepth 0 -name .git)
|
PROJECT_DIRS=$(find $INCLUDE_LINKS . -maxdepth "$MAXDEPTH" -mindepth 0 -name .git)
|
||||||
|
|
||||||
# Fetch the latest commits, if required
|
# Fetch the latest commits, if required
|
||||||
|
|
@ -270,7 +225,7 @@ if [[ $in_git_repo != 0 ]]; then
|
||||||
if [[ -d ".git" || -f ".git" ]] ; then
|
if [[ -d ".git" || -f ".git" ]] ; then
|
||||||
if GITOUT=$(git_output); then
|
if GITOUT=$(git_output); then
|
||||||
## Only output if there is some activities
|
## Only output if there is some activities
|
||||||
if [[ -n "$GITOUT" ]] ; then
|
if [[ ! -z "$GITOUT" ]] ; then
|
||||||
echo "${BOLD}${UNDERLINE}${YELLOW}$(basename "$DIR")${NORMAL}"
|
echo "${BOLD}${UNDERLINE}${YELLOW}$(basename "$DIR")${NORMAL}"
|
||||||
echo "$GITOUT"
|
echo "$GITOUT"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
@ -288,7 +243,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if GITOUT=$(git_output); then
|
if GITOUT=$(git_output); then
|
||||||
if [[ -n "$GITOUT" ]] ; then
|
if [[ ! -z "$GITOUT" ]] ; then
|
||||||
echo "$GITOUT"
|
echo "$GITOUT"
|
||||||
else
|
else
|
||||||
if [[ $AUTHOR = '.*' ]] ; then
|
if [[ $AUTHOR = '.*' ]] ; then
|
||||||
|
|
|
||||||
139
bin/git-summary
139
bin/git-summary
|
|
@ -3,16 +3,11 @@
|
||||||
|
|
||||||
cd "$(git root)" || { echo "Can't cd to top level directory";exit 1; }
|
cd "$(git root)" || { echo "Can't cd to top level directory";exit 1; }
|
||||||
|
|
||||||
PROJECT_FULL_PATH=
|
|
||||||
SUMMARY_BY_LINE=
|
SUMMARY_BY_LINE=
|
||||||
DEDUP_BY_EMAIL=
|
DEDUP_BY_EMAIL=
|
||||||
MERGES_ARG=
|
MERGES_ARG=
|
||||||
OUTPUT_STYLE=
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
--full-path)
|
|
||||||
PROJECT_FULL_PATH=1
|
|
||||||
;;
|
|
||||||
--line)
|
--line)
|
||||||
SUMMARY_BY_LINE=1
|
SUMMARY_BY_LINE=1
|
||||||
;;
|
;;
|
||||||
|
|
@ -22,10 +17,6 @@ for arg in "$@"; do
|
||||||
--no-merges)
|
--no-merges)
|
||||||
MERGES_ARG="--no-merges"
|
MERGES_ARG="--no-merges"
|
||||||
;;
|
;;
|
||||||
--output-style)
|
|
||||||
OUTPUT_STYLE="$2"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-*)
|
-*)
|
||||||
>&2 echo "unknown argument $arg found"
|
>&2 echo "unknown argument $arg found"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -49,33 +40,28 @@ if [ -n "$MERGES_ARG" ] && [ -n "$SUMMARY_BY_LINE" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
commit="HEAD"
|
|
||||||
if [ -n "$SUMMARY_BY_LINE" ]; then
|
|
||||||
paths=( "$@" )
|
|
||||||
else
|
|
||||||
[ $# -ne 0 ] && commit=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$PROJECT_FULL_PATH" ]]; then
|
commit=""
|
||||||
project=${PWD/${HOME}/\~}
|
test $# -ne 0 && commit=$*
|
||||||
else
|
project=${PWD##*/}
|
||||||
project=${PWD##*/}
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# get date for the given <commit>
|
# get date for the given <commit>
|
||||||
#
|
#
|
||||||
commit_date() {
|
|
||||||
|
date() {
|
||||||
# the $1 can be empty
|
# the $1 can be empty
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
git log $MERGES_ARG --pretty='format: %ai' "$1" | cut -d ' ' -f 2
|
git log $MERGES_ARG --pretty='format: %ai' $1 | cut -d ' ' -f 2
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# get active days for the given <commit>
|
# get active days for the given <commit>
|
||||||
#
|
#
|
||||||
|
|
||||||
active_days() {
|
active_days() {
|
||||||
commit_date "$1" | sort -r | uniq | awk '
|
# shellcheck disable=SC2086
|
||||||
|
date $1 | sort -r | uniq | awk '
|
||||||
{ sum += 1 }
|
{ sum += 1 }
|
||||||
END { print sum }
|
END { print sum }
|
||||||
'
|
'
|
||||||
|
|
@ -84,14 +70,16 @@ active_days() {
|
||||||
#
|
#
|
||||||
# get the commit total
|
# get the commit total
|
||||||
#
|
#
|
||||||
|
|
||||||
commit_count() {
|
commit_count() {
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
git rev-list $MERGES_ARG --count "$commit"
|
git log $MERGES_ARG --oneline $commit | wc -l | tr -d ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# total file count
|
# total file count
|
||||||
#
|
#
|
||||||
|
|
||||||
file_count() {
|
file_count() {
|
||||||
git ls-files | wc -l | tr -d ' '
|
git ls-files | wc -l | tr -d ' '
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +87,7 @@ file_count() {
|
||||||
#
|
#
|
||||||
# remove duplicate authors who belong to the same email address
|
# remove duplicate authors who belong to the same email address
|
||||||
#
|
#
|
||||||
|
|
||||||
dedup_by_email() {
|
dedup_by_email() {
|
||||||
# in:
|
# in:
|
||||||
# 27 luo zexuan <LuoZexuan@xxx.com>
|
# 27 luo zexuan <LuoZexuan@xxx.com>
|
||||||
|
|
@ -139,6 +128,7 @@ dedup_by_email() {
|
||||||
#
|
#
|
||||||
# list authors
|
# list authors
|
||||||
#
|
#
|
||||||
|
|
||||||
format_authors() {
|
format_authors() {
|
||||||
# a rare unicode character is used as separator to avoid conflicting with
|
# a rare unicode character is used as separator to avoid conflicting with
|
||||||
# author name. However, Linux column utility will escape tab if separator
|
# author name. However, Linux column utility will escape tab if separator
|
||||||
|
|
@ -156,17 +146,11 @@ format_authors() {
|
||||||
#
|
#
|
||||||
# fetch repository age from oldest commit
|
# fetch repository age from oldest commit
|
||||||
#
|
#
|
||||||
|
|
||||||
repository_age() {
|
repository_age() {
|
||||||
git log --reverse --pretty=oneline --format="%ar" | head -n 1 | LC_ALL=C sed 's/ago//'
|
git log --reverse --pretty=oneline --format="%ar" | head -n 1 | LC_ALL=C sed 's/ago//'
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# fetch repository age of the latest commit
|
|
||||||
#
|
|
||||||
last_active() {
|
|
||||||
git log --pretty=oneline --format="%ar" -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# list the last modified author for each line
|
# list the last modified author for each line
|
||||||
#
|
#
|
||||||
|
|
@ -174,86 +158,55 @@ single_file() {
|
||||||
while read -r data
|
while read -r data
|
||||||
do
|
do
|
||||||
if [[ $(file "$data") = *text* ]]; then
|
if [[ $(file "$data") = *text* ]]; then
|
||||||
git blame --line-porcelain "$data" 2>/dev/null | grep "^author " | LC_ALL=C sed -n 's/^author //p';
|
git blame --line-porcelain "$data" 2>/dev/null | grep "^author\ " | LC_ALL=C sed -n 's/^author //p';
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
current_branch_name() {
|
|
||||||
git rev-parse --abbrev-ref HEAD
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# list the author for all file
|
# list the author for all file
|
||||||
#
|
#
|
||||||
lines() {
|
lines() {
|
||||||
git ls-files -- "$@" | single_file
|
if [ -n "$1" ]; then
|
||||||
|
git ls-files -- $1 | single_file
|
||||||
|
else
|
||||||
|
git ls-files | single_file
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# get the number of the lines
|
# get the number of the lines
|
||||||
#
|
#
|
||||||
line_count() {
|
line_count() {
|
||||||
lines "$@" | wc -l
|
lines $1 | wc -l
|
||||||
}
|
}
|
||||||
|
|
||||||
uncommitted_changes_count() {
|
# summary
|
||||||
git status --porcelain | wc -l
|
|
||||||
}
|
|
||||||
|
|
||||||
|
echo
|
||||||
COLUMN_CMD_DELIMTER="¬" # Hopefully, this symbol is not used in branch names... I use it as a separator for columns
|
echo " project : $project"
|
||||||
SP="$COLUMN_CMD_DELIMTER|"
|
|
||||||
|
|
||||||
print_summary_by_line() {
|
|
||||||
if [ "$OUTPUT_STYLE" = "tabular" ]; then
|
|
||||||
tabular_headers="# Repo $SP Lines"
|
|
||||||
echo -e "$tabular_headers\n$project $SP $(line_count "${paths[@]}")" | column -t -s "$COLUMN_CMD_DELIMTER"
|
|
||||||
elif [ "$OUTPUT_STYLE" = "oneline" ]; then
|
|
||||||
echo "$project / lines: $(line_count "${paths[@]}")"
|
|
||||||
elif [ -n "$SUMMARY_BY_LINE" ]; then
|
|
||||||
echo
|
|
||||||
echo " project : $project"
|
|
||||||
echo " lines : $(line_count "${paths[@]}")"
|
|
||||||
echo " authors :"
|
|
||||||
lines "${paths[@]}" | sort | uniq -c | sort -rn | format_authors
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
print_summary() {
|
|
||||||
if [ "$OUTPUT_STYLE" = "tabular" ]; then
|
|
||||||
tabular_headers="# Repo $SP Age $SP Last active $SP Active on $SP Commits $SP Uncommitted $SP Branch"
|
|
||||||
echo -e "$tabular_headers\n$project $SP $(repository_age) $SP $(last_active) $SP $(active_days "$commit") days $SP $(commit_count "$commit") $SP $(uncommitted_changes_count) $SP $(current_branch_name)" | column -t -s "$COLUMN_CMD_DELIMTER"
|
|
||||||
elif [ "$OUTPUT_STYLE" = "oneline" ]; then
|
|
||||||
echo "$project / age: $(repository_age) / last active: $(last_active) / active on $(active_days "$commit") days / commits: $(commit_count "$commit") / uncommitted: $(uncommitted_changes_count) / branch: $(current_branch_name)"
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
echo " project : $project"
|
|
||||||
echo " repo age : $(repository_age)"
|
|
||||||
echo " branch: : $(current_branch_name)"
|
|
||||||
echo " last active : $(last_active)"
|
|
||||||
echo " active on : $(active_days "$commit") days"
|
|
||||||
echo " commits : $(commit_count "$commit")"
|
|
||||||
|
|
||||||
# The file count doesn't support passing a git ref so ignore it if a ref is given
|
|
||||||
if [ "$commit" = "HEAD" ]; then
|
|
||||||
echo " files : $(file_count)"
|
|
||||||
fi
|
|
||||||
echo " uncommitted : $(uncommitted_changes_count)"
|
|
||||||
echo " authors : "
|
|
||||||
if [ -n "$DEDUP_BY_EMAIL" ]; then
|
|
||||||
# the $commit can be empty
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
git shortlog $MERGES_ARG -n -s -e "$commit" | dedup_by_email | format_authors
|
|
||||||
else
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
git shortlog $MERGES_ARG -n -s "$commit" | format_authors
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -n "$SUMMARY_BY_LINE" ]; then
|
if [ -n "$SUMMARY_BY_LINE" ]; then
|
||||||
print_summary_by_line
|
echo " lines : $(line_count $commit)"
|
||||||
|
echo " authors :"
|
||||||
|
lines $commit | sort | uniq -c | sort -rn | format_authors
|
||||||
else
|
else
|
||||||
print_summary
|
|
||||||
|
# shellcheck disable=SC2046
|
||||||
|
echo " repo age :" $(repository_age)
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo " active :" "$(active_days $commit)" days
|
||||||
|
echo " commits :" "$(commit_count)"
|
||||||
|
if test "$commit" = ""; then
|
||||||
|
echo " files :" "$(file_count)"
|
||||||
|
fi
|
||||||
|
echo " authors : "
|
||||||
|
if [ -n "$DEDUP_BY_EMAIL" ]; then
|
||||||
|
# the $commit can be empty
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
git shortlog $MERGES_ARG -n -s -e $commit | dedup_by_email | format_authors
|
||||||
|
else
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
git shortlog $MERGES_ARG -n -s $commit | format_authors
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
27
bin/git-sync
27
bin/git-sync
|
|
@ -8,7 +8,6 @@ Usage:
|
||||||
${command} [<remote> <branch>]
|
${command} [<remote> <branch>]
|
||||||
${command} -h | --help
|
${command} -h | --help
|
||||||
${command} -s | --soft
|
${command} -s | --soft
|
||||||
${command} -f | --force
|
|
||||||
|
|
||||||
Sync local branch with <remote>/<branch>.
|
Sync local branch with <remote>/<branch>.
|
||||||
When <remote> and <branch> are not specified on the command line, upstream of local branch will be used by default.
|
When <remote> and <branch> are not specified on the command line, upstream of local branch will be used by default.
|
||||||
|
|
@ -23,9 +22,6 @@ Examples:
|
||||||
|
|
||||||
Sync without cleaning untracked files:
|
Sync without cleaning untracked files:
|
||||||
${command} -s
|
${command} -s
|
||||||
|
|
||||||
Sync without interaction:
|
|
||||||
${command} -f
|
|
||||||
EOS
|
EOS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,9 +36,6 @@ function main()
|
||||||
-s | --soft)
|
-s | --soft)
|
||||||
local soft="true"
|
local soft="true"
|
||||||
;;
|
;;
|
||||||
-f | --force)
|
|
||||||
local force="YES"
|
|
||||||
;;
|
|
||||||
* )
|
* )
|
||||||
if [ "${remote}" = "" ]; then
|
if [ "${remote}" = "" ]; then
|
||||||
local remote="$1"
|
local remote="$1"
|
||||||
|
|
@ -59,14 +52,14 @@ function main()
|
||||||
done
|
done
|
||||||
|
|
||||||
local remote_branch
|
local remote_branch
|
||||||
if [ -z "${remote}" ]; then
|
if [ "${remote}" = "" ]; then
|
||||||
if ! remote_branch="$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null)"; then
|
if ! remote_branch="$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null)"; then
|
||||||
echo "There is no upstream information of local branch."
|
echo "There is no upstream information of local branch."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
local branch="$(git rev-parse --abbrev-ref --symbolic-full-name @)"
|
local branch="$(git rev-parse --abbrev-ref --symbolic-full-name @)"
|
||||||
local remote=$(git config "branch.${branch}.remote")
|
local remote=$(git config "branch.${branch}.remote")
|
||||||
elif [ -z "${branch}" ]; then
|
elif [ "${branch}" = "" ]; then
|
||||||
echo -e "Error: too few arguments.\n"
|
echo -e "Error: too few arguments.\n"
|
||||||
_usage
|
_usage
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -74,16 +67,10 @@ function main()
|
||||||
remote_branch="${remote}/${branch}"
|
remote_branch="${remote}/${branch}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${force}" != "YES" ]; then
|
echo -n "Are you sure you want to clean all changes & sync with '${remote_branch}'? [y/N]: "
|
||||||
if [ "${soft}" = "true" ]; then
|
local res
|
||||||
echo -n "Are you sure you want to sync with '${remote_branch}'? [y/N]: "
|
read res
|
||||||
else
|
case "${res}" in
|
||||||
echo -n "Are you sure you want to clean all changes & sync with '${remote_branch}'? [y/N]: "
|
|
||||||
fi
|
|
||||||
local force
|
|
||||||
read -r force
|
|
||||||
fi
|
|
||||||
case "${force}" in
|
|
||||||
"Y" | "y" | "yes" | "Yes" | "YES" )
|
"Y" | "y" | "yes" | "Yes" | "YES" )
|
||||||
if [ "${soft}" = "true" ]; then
|
if [ "${soft}" = "true" ]; then
|
||||||
git fetch "${remote}" "${branch}" && git reset --hard "${remote_branch}"
|
git fetch "${remote}" "${branch}" && git reset --hard "${remote_branch}"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ USAGE(){
|
||||||
|
|
||||||
test $# -lt 1 && USAGE
|
test $# -lt 1 && USAGE
|
||||||
|
|
||||||
for filename in "$@"; do
|
for filename in $@; do
|
||||||
touch "$filename" \
|
touch "$filename" \
|
||||||
&& git add "$filename"
|
&& git add "$filename"
|
||||||
done
|
done
|
||||||
|
|
|
||||||
12
bin/git-undo
12
bin/git-undo
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
cstr="commits"
|
cstr="commits"
|
||||||
ccnt=$(git rev-list --count HEAD)
|
ccnt=$(git rev-list --count HEAD)
|
||||||
if [ "$ccnt" -eq 1 ]; then cstr="commit"; fi
|
if [ $ccnt -eq 1 ]; then cstr="commit"; fi
|
||||||
parm3=""
|
parm3=""
|
||||||
|
|
||||||
function _undo()
|
function _undo()
|
||||||
|
|
@ -11,14 +11,14 @@ function _undo()
|
||||||
undo_cnt=${2:-1}
|
undo_cnt=${2:-1}
|
||||||
reset=${3:-""}
|
reset=${3:-""}
|
||||||
|
|
||||||
if [ "$undo_cnt" -gt "$ccnt" ]; then
|
if [ $undo_cnt -gt $ccnt ]; then
|
||||||
echo "Only $ccnt $cstr, cannot undo $undo_cnt"
|
echo "Only $ccnt $cstr, cannot undo $undo_cnt"
|
||||||
elif [ "$type" = "hard" ] && [ "$ccnt" -eq "$undo_cnt" ]; then
|
elif [ "$type" = "hard" ] && [ $ccnt -eq $undo_cnt ]; then
|
||||||
echo "Cannot hard undo all commits"
|
echo "Cannot hard undo all commits"
|
||||||
elif [ "$type" = "soft" ] && [ "$ccnt" -eq 1 ]; then
|
elif [ "$type" = "soft" ] && [ $ccnt -eq 1 ]; then
|
||||||
git update-ref -d HEAD
|
git update-ref -d HEAD
|
||||||
else
|
else
|
||||||
git reset "--$type" "HEAD~$undo_cnt"
|
git reset --$type HEAD~$undo_cnt
|
||||||
fi
|
fi
|
||||||
if [ "$reset" != "" ]; then git reset; fi
|
if [ "$reset" != "" ]; then git reset; fi
|
||||||
}
|
}
|
||||||
|
|
@ -69,4 +69,4 @@ if [[ ! $parm2 =~ ^[1-9][0-9]*$ ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_undo "$parm1" "$parm2" "$parm3"
|
_undo $parm1 $parm2 $parm3
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Based on scripts from git-utils:
|
|
||||||
# * https://github.com/ddollar/git-utils/blob/master/git-unwip
|
|
||||||
|
|
||||||
# Check if the last commit is a 'WIP' commit
|
|
||||||
LAST_COMMIT=`git log -1 --pretty=%B | tr -d '[:space:]'`
|
|
||||||
|
|
||||||
if [ 'WIP' != $LAST_COMMIT ]; then
|
|
||||||
echo 'Last commit is not a WIP commit, so it will not be unWIP-ed.'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
git undo --soft
|
|
||||||
147
bin/git-utimes
147
bin/git-utimes
|
|
@ -2,130 +2,29 @@
|
||||||
#
|
#
|
||||||
# Change files modification time to their last commit date
|
# Change files modification time to their last commit date
|
||||||
#
|
#
|
||||||
|
if [ "$1" = --touch ]; then
|
||||||
# Bash unofficial strict mode
|
# Internal use option only just to parallelize things.
|
||||||
set -euo pipefail
|
|
||||||
IFS=$'\n\t'
|
|
||||||
|
|
||||||
if [[ "${1:-}" == "--newer" ]]; then
|
|
||||||
op=le
|
|
||||||
shift
|
shift
|
||||||
|
for f; do
|
||||||
|
iso_t=$(git --no-pager log --no-renames --pretty=format:%cI -1 @ -- "$f" 2>/dev/null)
|
||||||
|
if [ -n "$iso_t" ]; then
|
||||||
|
bsd=$(date -j > /dev/null 2>&1 && echo 'true')
|
||||||
|
if [ "$bsd" == "true" ]; then
|
||||||
|
t=$(date -j -f %Y-%m-%dT%H:%M:%S "$iso_t" +%Y%m%d%H%M.%S)
|
||||||
|
else
|
||||||
|
t=$(date -d"$iso_t" +%Y%m%d%H%M.%S)
|
||||||
|
fi
|
||||||
|
echo "+ touch -t $t $f" >&2
|
||||||
|
touch -t "$t" "$f"
|
||||||
|
fi
|
||||||
|
done
|
||||||
else
|
else
|
||||||
op=eq
|
opt_r=$(xargs -r false < /dev/null > /dev/null 2>&1 && echo '-r')
|
||||||
|
|
||||||
|
# `-n` should be limited or parallelization will not give effect,
|
||||||
|
# because all args will go into single worker.
|
||||||
|
NPROC=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null)
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
git ls-tree -z -r -t --name-only @ \
|
||||||
|
| xargs -0 -P${NPROC:-1} -n${NPROC:-1} $opt_r git utimes --touch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# BSD systems
|
|
||||||
if date -j &>/dev/null; then
|
|
||||||
stat_flags="-f %m"
|
|
||||||
date_flags="-r"
|
|
||||||
else
|
|
||||||
# Non-BSD systems
|
|
||||||
stat_flags="-c %Y"
|
|
||||||
date_flags="-d@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
bash_opts=()
|
|
||||||
if bash --help 2>&1 | grep -q -- '--noprofile'; then
|
|
||||||
bash_opts+=(--noprofile)
|
|
||||||
fi
|
|
||||||
if bash --help 2>&1 | grep -q -- '--norc'; then
|
|
||||||
bash_opts+=(--norc)
|
|
||||||
fi
|
|
||||||
|
|
||||||
status_opts=(--porcelain --short)
|
|
||||||
# %ct: committer date, UNIX timestamp / %at: author date, UNIX timestamp
|
|
||||||
log_opts=(--format='%ct')
|
|
||||||
if git status --help 2>&1 | grep -q -- "--no-renames"; then
|
|
||||||
status_opts+=(--no-renames)
|
|
||||||
log_opts+=(--no-renames)
|
|
||||||
fi
|
|
||||||
if git status --help 2>&1 | grep -q -- "--untracked-files"; then
|
|
||||||
status_opts+=(--untracked-files=no)
|
|
||||||
fi
|
|
||||||
if git status --help 2>&1 | grep -q -- "--ignored"; then
|
|
||||||
status_opts+=(--ignored=no)
|
|
||||||
fi
|
|
||||||
|
|
||||||
prefix="$(git rev-parse --show-prefix) "
|
|
||||||
strip="${#prefix}"
|
|
||||||
|
|
||||||
tmpfile=$(mktemp)
|
|
||||||
# shellcheck disable=SC2064
|
|
||||||
trap "rm -f '${tmpfile}'" 0
|
|
||||||
|
|
||||||
awk_flags=(
|
|
||||||
-F'\t'
|
|
||||||
-v date_flags="${date_flags}"
|
|
||||||
-v op="${op}"
|
|
||||||
-v stat_flags="${stat_flags}"
|
|
||||||
-v strip="${strip}"
|
|
||||||
-v tmpfile="${tmpfile}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# sanity check, not required:
|
|
||||||
if awk --help 2>&1 | grep -q -- '--posix'; then
|
|
||||||
awk_flags+=(--posix)
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -r -d '' awk_script <<"EOF" || true
|
|
||||||
BEGIN {
|
|
||||||
seen[""]=1
|
|
||||||
print "#!/usr/bin/env bash"
|
|
||||||
print "set +e"
|
|
||||||
print "t() {"
|
|
||||||
print " test -e \"$2\" || return 0"
|
|
||||||
printf(" test \"$(stat %s \"$2\" 2>/dev/null)\" -%s \"$1\" && return 0\n", stat_flags, op)
|
|
||||||
if (date_flags == "-d@") {
|
|
||||||
print " echo \"+ touch -h -d@$1 $2\""
|
|
||||||
print " touch -h -d@$1 \"$2\""
|
|
||||||
} else {
|
|
||||||
print " t=$(date -r$1 \"+%Y%m%d%H%M.%S\")"
|
|
||||||
print " echo \"+ touch -h -t $t $2\""
|
|
||||||
print " touch -h -t $t \"$2\""
|
|
||||||
}
|
|
||||||
print "}"
|
|
||||||
}
|
|
||||||
FILENAME==tmpfile {
|
|
||||||
skip[$1]=1
|
|
||||||
next
|
|
||||||
}
|
|
||||||
# skip blank lines
|
|
||||||
!/^$/ {
|
|
||||||
# skip deletes
|
|
||||||
if (substr($1, length($1), 1) ~ /D/) {
|
|
||||||
next
|
|
||||||
}
|
|
||||||
if (NF == 1) {
|
|
||||||
ct=$1
|
|
||||||
next
|
|
||||||
}
|
|
||||||
$2 = substr($2, strip, length($2)- strip + 1)
|
|
||||||
if ($2 in seen) {
|
|
||||||
next
|
|
||||||
}
|
|
||||||
if ($2 in skip) {
|
|
||||||
next
|
|
||||||
}
|
|
||||||
seen[$2]=1
|
|
||||||
# remove enclosing double quotes that git adds:
|
|
||||||
if (substr($2, 1, 1) == "\"" && substr($2, length($2), 1) == "\"") {
|
|
||||||
$2 = substr($2, 2, length($2) - 2)
|
|
||||||
# unescape remaining double quotes
|
|
||||||
gsub(/\\"/, "\"", $2)
|
|
||||||
# unescape escaped backslashes
|
|
||||||
gsub(/\\\\/, "\\", $2)
|
|
||||||
}
|
|
||||||
# escape apostrophes: ' => '\''
|
|
||||||
gsub(/'/, "'\\''", $2)
|
|
||||||
printf("t %s '%s'\n", ct, $2)
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# prefix is stripped:
|
|
||||||
git --no-pager status "${status_opts[@]}" . \
|
|
||||||
| cut -c 4- >"${tmpfile}"
|
|
||||||
|
|
||||||
# prefix is not stripped:
|
|
||||||
git --no-pager log --raw --no-merges "${log_opts[@]}" . \
|
|
||||||
| awk "${awk_flags[@]}" "${awk_script}" "${tmpfile}" - \
|
|
||||||
| BASH_ENV='' bash "${bash_opts[@]}" -
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Based on scripts from git-utils:
|
|
||||||
# * https://github.com/ddollar/git-utils/blob/master/git-wip
|
|
||||||
# * https://github.com/ddollar/git-utils/blob/master/git-addremove
|
|
||||||
|
|
||||||
git add --all
|
|
||||||
git commit --all --message="WIP"
|
|
||||||
|
|
@ -3,10 +3,10 @@ index e49cd24..4ae28b5 100755
|
||||||
--- a/bin/git-extras
|
--- a/bin/git-extras
|
||||||
+++ b/bin/git-extras
|
+++ b/bin/git-extras
|
||||||
@@ -4,13 +4,12 @@ VERSION="4.3.0"
|
@@ -4,13 +4,12 @@ VERSION="4.3.0"
|
||||||
INSTALL_SCRIPT="https://raw.githubusercontent.com/tj/git-extras/main/install.sh"
|
INSTALL_SCRIPT="https://raw.githubusercontent.com/tj/git-extras/master/install.sh"
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
- local bin="$(command -v git-extras)"
|
- local bin="$(which git-extras)"
|
||||||
- local prefix=${bin%/*/*}
|
- local prefix=${bin%/*/*}
|
||||||
- local orig=$PWD
|
- local orig=$PWD
|
||||||
-
|
-
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,5 @@ err() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! command -v column >/dev/null 2>&1; then
|
if ! command -v column >/dev/null 2>&1; then
|
||||||
err "Need to install dependency 'column' before installation (can be found in bsdmainutils)"
|
err "Need to install dependency 'column' before installation"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ err() {
|
||||||
}
|
}
|
||||||
|
|
||||||
make_doc() {
|
make_doc() {
|
||||||
echo "touch man/git-$1.md && make man/git-$1.{1,html}"
|
echo "'touch man/git-$1.md && make man/git-$1.{1,html}'"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_bash_script() {
|
check_bash_script() {
|
||||||
|
|
@ -25,7 +25,7 @@ check_bash_script() {
|
||||||
|
|
||||||
check_git_extras_cmd_list() {
|
check_git_extras_cmd_list() {
|
||||||
local whitelist=('extras')
|
local whitelist=('extras')
|
||||||
for cmd in "${whitelist[@]}"; do
|
for cmd in ${whitelist[*]}; do
|
||||||
test "$1" == "$cmd" && return
|
test "$1" == "$cmd" && return
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -47,11 +47,6 @@ check_documentation() {
|
||||||
err "Create man/$cmd.1 and man/$cmd.html via $(make_doc "$1")"
|
err "Create man/$cmd.1 and man/$cmd.html via $(make_doc "$1")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "man/$cmd.md" -nt "man/$cmd.1" ] || [ "man/$cmd.md" -nt "man/$cmd.html" ]
|
|
||||||
then
|
|
||||||
err "man/$cmd.md, man/$cmd.1, and man/$cmd.html all exist, but man/$cmd.md is newer. You should rm man/$cmd.{1,html} && $(make_doc "$1")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_git_extras_cmd_list "$@"
|
check_git_extras_cmd_list "$@"
|
||||||
check_man_page_index "$@"
|
check_man_page_index "$@"
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +54,7 @@ check_documentation() {
|
||||||
check_Commands_page() {
|
check_Commands_page() {
|
||||||
# These are special cases. All listed together, so we ignore them
|
# These are special cases. All listed together, so we ignore them
|
||||||
local whitelist=('bug' 'chore' 'feature' 'refactor')
|
local whitelist=('bug' 'chore' 'feature' 'refactor')
|
||||||
for cmd in "${whitelist[@]}"; do
|
for cmd in ${whitelist[*]}; do
|
||||||
test "$1" == "$cmd" && return
|
test "$1" == "$cmd" && return
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -82,9 +77,12 @@ check() {
|
||||||
check_completion "$1"
|
check_completion "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
test $# == 0 && set -- $(find bin | cut -b 5- | xargs)
|
usage() {
|
||||||
|
echo >&2 "Usage: ./check_integrity.sh <command-name> [<command-name2> ...]"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
./bin/git-utimes --newer
|
test $# == 0 && usage
|
||||||
|
|
||||||
for name in "$@"; do
|
for name in "$@"; do
|
||||||
name=${name#git-}
|
name=${name#git-}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,5 @@
|
||||||
# shellcheck shell=bash
|
|
||||||
# bash completion support for git-extras.
|
# bash completion support for git-extras.
|
||||||
|
|
||||||
__gitex_heads_unique() {
|
|
||||||
local branch specified=("${COMP_WORDS[@]:2}")
|
|
||||||
for branch in $(__git_heads); do
|
|
||||||
[[ " ${specified[*]} " == *" $branch "* ]] || printf '%s\n' "$branch"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_authors(){
|
|
||||||
__gitcomp "-l --list --no-email"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_browse(){
|
|
||||||
__git_complete_remote_or_refspec
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_browse_ci(){
|
|
||||||
__git_complete_remote_or_refspec
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_brv(){
|
|
||||||
__gitcomp "-r --reverse"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_changelog(){
|
_git_changelog(){
|
||||||
local s_opts=( '-a' '-l' '-t' '-f' '-s' '-n' '-p' '-x' '-h' '?' )
|
local s_opts=( '-a' '-l' '-t' '-f' '-s' '-n' '-p' '-x' '-h' '?' )
|
||||||
local l_opts=(
|
local l_opts=(
|
||||||
|
|
@ -45,29 +21,8 @@ _git_changelog(){
|
||||||
__gitcomp "$merged_opts_str"
|
__gitcomp "$merged_opts_str"
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_coauthor(){
|
_git_authors(){
|
||||||
local oldIfs=$IFS
|
__gitcomp "-l --list --no-email"
|
||||||
IFS=$'\n'
|
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
||||||
local selection=
|
|
||||||
if ((COMP_CWORD == 2)); then
|
|
||||||
for line in $(git authors --list); do
|
|
||||||
selection+="${line% *}"$'\n'
|
|
||||||
done
|
|
||||||
elif ((COMP_CWORD == 3)); then
|
|
||||||
local chosen_name="${COMP_WORDS[COMP_CWORD-1]}"
|
|
||||||
for line in $(git authors --list); do
|
|
||||||
if [ "$chosen_name" = "${line% *}" ]; then
|
|
||||||
local email=${line#*<}
|
|
||||||
email=${email%>*}
|
|
||||||
selection+="$email"$'\n'
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
compopt +o default
|
|
||||||
compopt -o filenames
|
|
||||||
COMPREPLY=($(compgen -W "$selection" -- "$cur"))
|
|
||||||
IFS=$oldIfs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_contrib(){
|
_git_contrib(){
|
||||||
|
|
@ -82,10 +37,6 @@ _git_contrib(){
|
||||||
COMPREPLY=($(compgen -W "$all" -- "$cur"))
|
COMPREPLY=($(compgen -W "$all" -- "$cur"))
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_commits_since(){
|
|
||||||
__gitcomp "-r --ref"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_count(){
|
_git_count(){
|
||||||
__gitcomp "--all"
|
__gitcomp "--all"
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +46,7 @@ __git_cp(){
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_delete_branch(){
|
_git_delete_branch(){
|
||||||
__gitcomp "$(__gitex_heads_unique)"
|
__gitcomp "$(__git_heads)"
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_delete_squashed_branches(){
|
_git_delete_squashed_branches(){
|
||||||
|
|
@ -115,7 +66,6 @@ _git_effort(){
|
||||||
|
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--*)
|
--*)
|
||||||
# shellcheck disable=SC2154
|
|
||||||
__gitcomp "
|
__gitcomp "
|
||||||
--above
|
--above
|
||||||
$__git_log_common_options
|
$__git_log_common_options
|
||||||
|
|
@ -131,7 +81,7 @@ _git_extras(){
|
||||||
}
|
}
|
||||||
|
|
||||||
__git_extras_workflow(){
|
__git_extras_workflow(){
|
||||||
__gitcomp "$(__git_heads | grep -- "^$1/" | sed s/^"$1"\\///g) finish"
|
__gitcomp "$(__git_heads | grep -- ^$1/ | sed s/^$1\\///g) finish"
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_feature(){
|
_git_feature(){
|
||||||
|
|
@ -145,20 +95,16 @@ _git_graft(){
|
||||||
_git_ignore(){
|
_git_ignore(){
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--*)
|
--*)
|
||||||
__gitcomp "--global --local --private --edit --remove"
|
__gitcomp "--global --local --private"
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
-*)
|
-*)
|
||||||
__gitcomp "--global --local --private --edit --remove -g -l -p -e -r"
|
__gitcomp "--global --local --private -g -l -p"
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_info(){
|
|
||||||
__gitcomp "--color -c --no-config"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_missing(){
|
_git_missing(){
|
||||||
# Suggest all known refs
|
# Suggest all known refs
|
||||||
__gitcomp "$(git for-each-ref --format='%(refname:short)')"
|
__gitcomp "$(git for-each-ref --format='%(refname:short)')"
|
||||||
|
|
@ -181,29 +127,15 @@ _git_reauthor(){
|
||||||
__gitcomp "${comp}"
|
__gitcomp "${comp}"
|
||||||
}
|
}
|
||||||
|
|
||||||
__git_extras_rename(){
|
_git_scp(){
|
||||||
if ((COMP_CWORD == 2 || COMP_CWORD == 3)); then
|
|
||||||
__gitcomp "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_rename_branch(){
|
|
||||||
__git_extras_rename "$(__git_heads)"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_rename_remote(){
|
|
||||||
__git_extras_rename "$(__git_remotes)"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_rename_tag(){
|
|
||||||
__git_extras_rename "$(__git_tags)"
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_rscp(){
|
|
||||||
__git_complete_remote_or_refspec
|
__git_complete_remote_or_refspec
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_scp(){
|
_git_stamp(){
|
||||||
|
__gitcomp '--replace -r'
|
||||||
|
}
|
||||||
|
|
||||||
|
_git_rscp(){
|
||||||
__git_complete_remote_or_refspec
|
__git_complete_remote_or_refspec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,10 +143,18 @@ _git_squash(){
|
||||||
__gitcomp "$(__git_heads)"
|
__gitcomp "$(__git_heads)"
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_stamp(){
|
|
||||||
__gitcomp '--replace -r'
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_undo(){
|
_git_undo(){
|
||||||
__gitcomp "--hard --soft -h -s"
|
__gitcomp "--hard --soft -h -s"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_git_info(){
|
||||||
|
__gitcomp "--color -c --no-config"
|
||||||
|
}
|
||||||
|
|
||||||
|
_git_browse(){
|
||||||
|
__git_complete_remote_or_refspec
|
||||||
|
}
|
||||||
|
|
||||||
|
_git_browse_ci(){
|
||||||
|
__git_complete_remote_or_refspec
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ __gitex_remote_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a remote_names
|
declare -a remote_names
|
||||||
remote_names=(${(f)"$(_call_program remotes git remote 2>/dev/null)"})
|
remote_names=(${(f)"$(_call_program remotes git remote 2>/dev/null)"})
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted remote-names expl remote-name compadd $* - $remote_names
|
_wanted remote-names expl remote-name compadd $* - $remote_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ __gitex_tag_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a tag_names
|
declare -a tag_names
|
||||||
tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
|
tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted tag-names expl tag-name compadd $* - $tag_names
|
_wanted tag-names expl tag-name compadd $* - $tag_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,24 +68,15 @@ __gitex_branch_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a branch_names
|
declare -a branch_names
|
||||||
branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
|
branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted branch-names expl branch-name compadd $* - $branch_names
|
_wanted branch-names expl branch-name compadd $* - $branch_names
|
||||||
}
|
}
|
||||||
|
|
||||||
__gitex_branch_names_unique() {
|
|
||||||
local expl
|
|
||||||
declare -a branch_names already_specified
|
|
||||||
branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
|
|
||||||
__gitex_command_successful || return
|
|
||||||
already_specified=(${words[2,-1]})
|
|
||||||
_wanted branch-names expl branch-name compadd -F already_specified $* - $branch_names
|
|
||||||
}
|
|
||||||
|
|
||||||
__gitex_specific_branch_names() {
|
__gitex_specific_branch_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a branch_names
|
declare -a branch_names
|
||||||
branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/})
|
branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/})
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted branch-names expl branch-name compadd - $branch_names
|
_wanted branch-names expl branch-name compadd - $branch_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,31 +88,16 @@ __gitex_submodule_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a submodule_names
|
declare -a submodule_names
|
||||||
submodule_names=(${(f)"$(_call_program branchrefs git submodule status | awk '{print $2}')"}) # '
|
submodule_names=(${(f)"$(_call_program branchrefs git submodule status | awk '{print $2}')"}) # '
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted submodule-names expl submodule-name compadd $* - $submodule_names
|
_wanted submodule-names expl submodule-name compadd $* - $submodule_names
|
||||||
}
|
}
|
||||||
|
|
||||||
__gitex_workspace_names() {
|
|
||||||
local expl
|
|
||||||
declare -a workspace_names
|
|
||||||
workspace_names=($(git bulk --listall | awk '{print $1}' | cut -d "." -f 2))
|
|
||||||
__gitex_command_successful || return
|
|
||||||
_wanted workspace-names expl workspace-names compadd $* - $workspace_names
|
|
||||||
}
|
|
||||||
|
|
||||||
__gitex_author_names() {
|
__gitex_author_names() {
|
||||||
local expl
|
local expl
|
||||||
declare -a author_names
|
declare -a author_names
|
||||||
author_names=(${(f)"$(_call_program branchrefs git log --format='%aN' | sort -u)"})
|
author_names=(${(f)"$(_call_program branchrefs git log --format='%aN' | sort -u)"})
|
||||||
__gitex_command_successful || return
|
__git_command_successful || return
|
||||||
_wanted author-names expl author-name compadd $* - $author_names
|
|
||||||
}
|
|
||||||
|
|
||||||
__gitex_author_emails() {
|
|
||||||
local expl
|
|
||||||
declare -a author_names
|
|
||||||
author_names=(${(f)"$(_call_program branchrefs git log --format='%aE' | sort -u)"})
|
|
||||||
__gitex_command_successful || return
|
|
||||||
_wanted author-names expl author-name compadd $* - $author_names
|
_wanted author-names expl author-name compadd $* - $author_names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,27 +109,6 @@ _git-authors() {
|
||||||
'--no-email[without email]' \
|
'--no-email[without email]' \
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-brv() {
|
|
||||||
_arguments \
|
|
||||||
'(-r --reverse)'{-r,--reverse}'[reverse order]'
|
|
||||||
}
|
|
||||||
|
|
||||||
_git-bulk() {
|
|
||||||
_arguments \
|
|
||||||
'-a[Run a git command on all workspaces and their repositories.]' \
|
|
||||||
'-g[Ask the user for confirmation on every execution (guarded mode).]' \
|
|
||||||
'-w[Run the git command on the specified workspace.]:workspace-name:__gitex_workspace_names' \
|
|
||||||
'-q[Suppress bulk output about current execution (quiet mode).]' \
|
|
||||||
'--no-follow-symlinks[Do not traverse symbolic links when searching for git repositories.]' \
|
|
||||||
'--no-follow-hidden[Do not traverse hidden directories when searching for git repositories.]' \
|
|
||||||
'--addworkspace[Register a workspace for bulk operations.]' \
|
|
||||||
'--removeworkspace[Remove the specified workspace.]:workspace-name:__gitex_workspace_names' \
|
|
||||||
'--addcurrent[Adds the current directory as workspace to git bulk operations]' \
|
|
||||||
'--purge[Removes all defined repository locations.]' \
|
|
||||||
'--listall[List all registered repositories.]' \
|
|
||||||
'--help[Show the help.]'
|
|
||||||
}
|
|
||||||
|
|
||||||
_git-changelog() {
|
_git-changelog() {
|
||||||
_arguments \
|
_arguments \
|
||||||
'(-l --list)'{-l,--list}'[list commits]' \
|
'(-l --list)'{-l,--list}'[list commits]' \
|
||||||
|
|
@ -167,13 +122,8 @@ _git-clear() {
|
||||||
|
|
||||||
_git-coauthor() {
|
_git-coauthor() {
|
||||||
_arguments \
|
_arguments \
|
||||||
':co-author[co-author to add]:__gitex_author_names' \
|
':co-author[co-author to add]' \
|
||||||
':co-author-email[email address of co-author to add]:__gitex_author_emails'
|
':co-author-email[email address of co-author to add]'
|
||||||
}
|
|
||||||
|
|
||||||
_git-commits-since() {
|
|
||||||
_arguments \
|
|
||||||
'(-r --ref)'{-r,--ref}'[show commits since ref]'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-contrib() {
|
_git-contrib() {
|
||||||
|
|
@ -210,12 +160,8 @@ _git-create-branch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-delete-branch() {
|
_git-delete-branch() {
|
||||||
__gitex_branch_names_unique
|
|
||||||
}
|
|
||||||
|
|
||||||
_git-delete-gone-branches() {
|
|
||||||
_arguments \
|
_arguments \
|
||||||
'(-n --dry-run)'{-n,--dry-run}'[show branches that would be deleted without deleting]'
|
':branch-name:__gitex_branch_names'
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-delete-squashed-branches() {
|
_git-delete-squashed-branches() {
|
||||||
|
|
@ -317,12 +263,9 @@ _git-guilt() {
|
||||||
|
|
||||||
_git-ignore() {
|
_git-ignore() {
|
||||||
_arguments -C \
|
_arguments -C \
|
||||||
'(--local -l)'{--local,-l}'[set context to local gitignore]' \
|
'(--local -l)'{--local,-l}'[show local gitignore]' \
|
||||||
'(--global -g)'{--global,-g}'[set context to global gitignore]' \
|
'(--global -g)'{--global,-g}'[show global gitignore]' \
|
||||||
'(--private -p)'{--private,-p}'[set context to private gitignore]' \
|
'(--private -p)'{--private,-p}'[show repo gitignore]'
|
||||||
'(--edit -e)'{--edit,-e}'[set action to edit]' \
|
|
||||||
'(--remove -r)'{--remove,-r}'[set action to remove]' \
|
|
||||||
'*:filename:_files'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -359,14 +302,6 @@ _git-release() {
|
||||||
'--[The arguments listed after "--" separator will be passed to pre/post-release hook.]'
|
'--[The arguments listed after "--" separator will be passed to pre/post-release hook.]'
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-rename-file() {
|
|
||||||
_arguments -C \
|
|
||||||
'-h[show usage information]' \
|
|
||||||
'--help[show usage information]' \
|
|
||||||
'1:source:__git_files' \
|
|
||||||
'2:destination:__git_files'
|
|
||||||
}
|
|
||||||
|
|
||||||
_git-squash() {
|
_git-squash() {
|
||||||
_arguments '--squash-msg[commit with the squashed commit messages]'
|
_arguments '--squash-msg[commit with the squashed commit messages]'
|
||||||
_arguments \
|
_arguments \
|
||||||
|
|
@ -392,7 +327,6 @@ _git-standup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_git-summary() {
|
_git-summary() {
|
||||||
_arguments '--full-path[show repository full path]'
|
|
||||||
_arguments '--line[summarize with lines rather than commits]'
|
_arguments '--line[summarize with lines rather than commits]'
|
||||||
_arguments '--dedup-by-email[remove duplicate users by the email address]'
|
_arguments '--dedup-by-email[remove duplicate users by the email address]'
|
||||||
_arguments '--no-merges[exclude merge commits]'
|
_arguments '--no-merges[exclude merge commits]'
|
||||||
|
|
@ -409,7 +343,7 @@ zstyle -g existing_user_commands ':completion:*:*:git:*' user-commands
|
||||||
|
|
||||||
zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
||||||
alias:'define, search and show aliases' \
|
alias:'define, search and show aliases' \
|
||||||
abort:'abort current revert, merge, rebase, or cherry-pick process' \
|
abort:'abort current merge, rebase, or cherry-pick process' \
|
||||||
archive-file:'export the current head of the git repository to an archive' \
|
archive-file:'export the current head of the git repository to an archive' \
|
||||||
authors:'generate authors report' \
|
authors:'generate authors report' \
|
||||||
browse:'open repo website in browser' \
|
browse:'open repo website in browser' \
|
||||||
|
|
@ -423,12 +357,10 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
||||||
clear:'rigorously clean up a repository' \
|
clear:'rigorously clean up a repository' \
|
||||||
coauthor:'add a co-author to the last commit' \
|
coauthor:'add a co-author to the last commit' \
|
||||||
commits-since:'show commit logs since some date' \
|
commits-since:'show commit logs since some date' \
|
||||||
continue:'continue current revert, merge, rebase, or cherry-pick process' \
|
|
||||||
contrib:'show user contributions' \
|
contrib:'show user contributions' \
|
||||||
count:'show commit count' \
|
count:'show commit count' \
|
||||||
create-branch:'create branches' \
|
create-branch:'create branches' \
|
||||||
delete-branch:'delete branches' \
|
delete-branch:'delete branches' \
|
||||||
delete-gone-branches:'delete branches whose remote is gone' \
|
|
||||||
delete-merged-branches:'delete merged branches' \
|
delete-merged-branches:'delete merged branches' \
|
||||||
delete-squashed-branches:'delete squashed branches' \
|
delete-squashed-branches:'delete squashed branches' \
|
||||||
delete-submodule:'delete submodules' \
|
delete-submodule:'delete submodules' \
|
||||||
|
|
@ -438,14 +370,13 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
||||||
extras:'awesome git utilities' \
|
extras:'awesome git utilities' \
|
||||||
feature:'create/merge feature branch' \
|
feature:'create/merge feature branch' \
|
||||||
force-clone:'overwrite local repositories with clone' \
|
force-clone:'overwrite local repositories with clone' \
|
||||||
fork:'fork a repo on GitHub' \
|
fork:'fork a repo on github' \
|
||||||
fresh-branch:'create fresh branches' \
|
fresh-branch:'create fresh branches' \
|
||||||
get:'clone a repository in a directory' \
|
gh-pages:'create the github pages branch' \
|
||||||
gh-pages:'create the GitHub pages branch' \
|
|
||||||
graft:'merge and destroy a given branch' \
|
graft:'merge and destroy a given branch' \
|
||||||
guilt:'calculate change between two revisions' \
|
guilt:'calculate change between two revisions' \
|
||||||
ignore-io:'get sample gitignore file' \
|
ignore-io:'get sample gitignore file' \
|
||||||
ignore:'Modify or display .gitignore files' \
|
ignore:'add .gitignore patterns' \
|
||||||
info:'returns information on current repository' \
|
info:'returns information on current repository' \
|
||||||
local-commits:'list local commits' \
|
local-commits:'list local commits' \
|
||||||
lock:'lock a file excluded from version control' \
|
lock:'lock a file excluded from version control' \
|
||||||
|
|
@ -465,7 +396,6 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
||||||
refactor:'create refactor branch' \
|
refactor:'create refactor branch' \
|
||||||
release:'commit, tag and push changes to the repository' \
|
release:'commit, tag and push changes to the repository' \
|
||||||
rename-branch:'rename a branch' \
|
rename-branch:'rename a branch' \
|
||||||
rename-file:'rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity' \
|
|
||||||
rename-tag:'rename a tag' \
|
rename-tag:'rename a tag' \
|
||||||
rename-remote:'rename a remote' \
|
rename-remote:'rename a remote' \
|
||||||
repl:'git read-eval-print-loop' \
|
repl:'git read-eval-print-loop' \
|
||||||
|
|
@ -485,6 +415,4 @@ zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
|
||||||
touch:'touch and add file to the index' \
|
touch:'touch and add file to the index' \
|
||||||
undo:'remove latest commits' \
|
undo:'remove latest commits' \
|
||||||
unlock:'unlock a file excluded from version control' \
|
unlock:'unlock a file excluded from version control' \
|
||||||
utimes:'change files modification time to their last commit date' \
|
utimes:'change files modification time to their last commit date'
|
||||||
unwip:'undo a WIP commit' \
|
|
||||||
wip:'create a WIP commit'
|
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,11 @@ set __fish_git_extras_commands \
|
||||||
"force-clone:overwrite local repositories with clone" \
|
"force-clone:overwrite local repositories with clone" \
|
||||||
"fork:Fork a repo on github" \
|
"fork:Fork a repo on github" \
|
||||||
"fresh-branch:Create fresh branches" \
|
"fresh-branch:Create fresh branches" \
|
||||||
"get:Clone a repository in a directory" \
|
|
||||||
"gh-pages:Create the GitHub Pages branch" \
|
"gh-pages:Create the GitHub Pages branch" \
|
||||||
"graft:Merge and destroy a given branch" \
|
"graft:Merge and destroy a given branch" \
|
||||||
"guilt:calculate change between two revisions" \
|
"guilt:calculate change between two revisions" \
|
||||||
"ignore-io:Get sample gitignore file" \
|
"ignore-io:Get sample gitignore file" \
|
||||||
"ignore:Modify or display .gitignore files" \
|
"ignore:Add .gitignore patterns" \
|
||||||
"info:Returns information on current repository" \
|
"info:Returns information on current repository" \
|
||||||
"local-commits:List local commits" \
|
"local-commits:List local commits" \
|
||||||
"lock:Lock a file excluded from version control" \
|
"lock:Lock a file excluded from version control" \
|
||||||
|
|
@ -50,7 +49,6 @@ set __fish_git_extras_commands \
|
||||||
"rebase-patch:Rebases a patch" \
|
"rebase-patch:Rebases a patch" \
|
||||||
"release:Commit, tag and push changes to the repository" \
|
"release:Commit, tag and push changes to the repository" \
|
||||||
"rename-branch:rename local branch and push to remote" \
|
"rename-branch:rename local branch and push to remote" \
|
||||||
"rename-file:rename a file or directory and ensure Git recognizes the change, regardless of filesystem case-sensitivity" \
|
|
||||||
"rename-remote:Rename a remote" \
|
"rename-remote:Rename a remote" \
|
||||||
"rename-tag:Rename a tag" \
|
"rename-tag:Rename a tag" \
|
||||||
"repl:git read-eval-print-loop" \
|
"repl:git read-eval-print-loop" \
|
||||||
|
|
@ -72,22 +70,20 @@ set __fish_git_extras_commands \
|
||||||
"unlock:Unlock a file excluded from version control"
|
"unlock:Unlock a file excluded from version control"
|
||||||
|
|
||||||
# completion for git-extras itself
|
# completion for git-extras itself
|
||||||
complete -c git -f -n __fish_git_needs_command -a extras -d 'GIT utilities: repo summary, repl, changelog population, and more'
|
complete -c git -f -n '__fish_git_needs_command' -a 'extras' -d 'GIT utilities: repo summary, repl, changelog population, and more'
|
||||||
complete -c git -f -n '__fish_git_using_command extras' -s h -l help -d 'Show the help message, can be used for any git-extras commands'
|
complete -c git -f -n '__fish_git_using_command extras' -s h -l help -d 'Show the help message, can be used for any git-extras commands'
|
||||||
complete -c git -f -n '__fish_git_using_command extras' -s v -l version -d 'Show git-extras version number'
|
complete -c git -f -n '__fish_git_using_command extras' -s v -l version -d 'Show git-extras version number'
|
||||||
complete -c git -f -n '__fish_git_using_command extras; and not contains -- update (commandline -opc)' -a update -d 'Self update'
|
complete -c git -f -n '__fish_git_using_command extras; and not contains -- update (commandline -opc)' -a "update" -d 'Self update'
|
||||||
|
|
||||||
# completion for git-extras provided commands
|
# completion for git-extras provided commands
|
||||||
set __fish_git_extras_commands (printf -- '%s\n' $__fish_git_extras_commands | sed 's/:/\textras:/' | string collect | string escape)
|
set __fish_git_extras_commands (printf -- '%s\n' $__fish_git_extras_commands | sed 's/:/\textras:/' | string collect | string escape)
|
||||||
complete -c git -n __fish_git_needs_command -a "$__fish_git_extras_commands"
|
complete -c git -n '__fish_git_needs_command' -a "$__fish_git_extras_commands"
|
||||||
# authors
|
# authors
|
||||||
complete -c git -f -n '__fish_git_using_command authors' -s l -l list -d 'show authors'
|
complete -c git -f -n '__fish_git_using_command authors' -s l -l list -d 'show authors'
|
||||||
complete -c git -f -n '__fish_git_using_command authors' -l no-email -d 'without email'
|
complete -c git -f -n '__fish_git_using_command authors' -l no-email -d 'without email'
|
||||||
# brv
|
|
||||||
complete -c git -f -n '__fish_git_using_command brv' -s r -l reverse -d 'reverse the sort order'
|
|
||||||
# bulk
|
# bulk
|
||||||
complete -c git -n '__fish_git_using_command bulk' -s a -d 'Run a git command on all workspaces and their repositories'
|
complete -c git -n '__fish_git_using_command bulk' -s a -d 'Run a git command on all workspaces and their repositories'
|
||||||
complete -c git -n '__fish_git_using_command bulk' -s g -d 'Ask the user for confirmation on every execution'
|
complete -c git -n '__fish_git_using_command bulk' -s g -d 'Ask the user for confirmation on every execution'
|
||||||
complete -c git -x -n '__fish_git_using_command bulk' -s w -d 'Run on specified workspace'
|
complete -c git -x -n '__fish_git_using_command bulk' -s w -d 'Run on specified workspace'
|
||||||
complete -c git -x -n '__fish_git_using_command bulk' -l addworkspace -d 'Register a workspace for builk operations'
|
complete -c git -x -n '__fish_git_using_command bulk' -l addworkspace -d 'Register a workspace for builk operations'
|
||||||
complete -c git -x -n '__fish_git_using_command bulk; and contains addworkspace (commandline -opc)' -l addworkspace -d 'the URL or file with URLs to be added'
|
complete -c git -x -n '__fish_git_using_command bulk; and contains addworkspace (commandline -opc)' -l addworkspace -d 'the URL or file with URLs to be added'
|
||||||
|
|
@ -106,33 +102,6 @@ complete -c git -f -n '__fish_git_using_command changelog' -s n -l no-merges -d
|
||||||
complete -c git -f -n '__fish_git_using_command changelog' -s m -l merges-only -d 'Uses only merge commits (commits with more than 1 parent) for generated changelog'
|
complete -c git -f -n '__fish_git_using_command changelog' -s m -l merges-only -d 'Uses only merge commits (commits with more than 1 parent) for generated changelog'
|
||||||
complete -c git -f -n '__fish_git_using_command changelog' -s p -l prune-old -d 'Replace existing changelog entirely with newly generated content'
|
complete -c git -f -n '__fish_git_using_command changelog' -s p -l prune-old -d 'Replace existing changelog entirely with newly generated content'
|
||||||
complete -c git -f -n '__fish_git_using_command changelog' -s x -l stdout -d 'Write output to stdout instead of to a new changelog file'
|
complete -c git -f -n '__fish_git_using_command changelog' -s x -l stdout -d 'Write output to stdout instead of to a new changelog file'
|
||||||
# coauthor
|
|
||||||
function __fish_git_arg_number -a number
|
|
||||||
set -l cmd (commandline -opc)
|
|
||||||
test (count $cmd) -eq $number
|
|
||||||
end
|
|
||||||
function __fish_git_extra_coauthor_name
|
|
||||||
for line in (git authors --list)
|
|
||||||
printf '%s\n' $line | string replace --regex ' <.*' ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function __fish_git_extra_coauthor_email
|
|
||||||
set -l cmd (commandline -opc)
|
|
||||||
# name provided in the previous positional argument
|
|
||||||
set -l name $cmd[3]
|
|
||||||
|
|
||||||
for line in (git authors --list)
|
|
||||||
set -l loop_name (printf '%s\n' $line | string replace --regex ' <.*' '')
|
|
||||||
|
|
||||||
if test "$name" = "$loop_name"
|
|
||||||
printf '%s\n' $line | string replace --regex '.*?<' '' | string replace --regex '>.*?' ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
complete -c git -f -n '__fish_git_using_command coauthor; and __fish_git_arg_number 2' -a '(__fish_git_extra_coauthor_name)'
|
|
||||||
complete -c git -f -n '__fish_git_using_command coauthor; and __fish_git_arg_number 3' -a '(__fish_git_extra_coauthor_email)'
|
|
||||||
# commits-since
|
|
||||||
complete -c git -f -n '__fish_git_using_command commits-since' -s r -l ref -d 'show commits since ref'
|
|
||||||
# count
|
# count
|
||||||
complete -c git -f -n '__fish_git_using_command count' -l all -d 'detailed commit count'
|
complete -c git -f -n '__fish_git_using_command count' -l all -d 'detailed commit count'
|
||||||
# create-branch
|
# create-branch
|
||||||
|
|
@ -149,24 +118,22 @@ complete -c git -x -n "__fish_git_using_command delete-tag" -a '(__fish_git for-
|
||||||
complete -c git -f -n '__fish_git_using_command effort' -l above -d 'ignore file with less than x commits'
|
complete -c git -f -n '__fish_git_using_command effort' -l above -d 'ignore file with less than x commits'
|
||||||
# feature
|
# feature
|
||||||
complete -c git -x -n '__fish_git_using_command feature' -s a -l alias -d 'use branch_prefix instead of feature'
|
complete -c git -x -n '__fish_git_using_command feature' -s a -l alias -d 'use branch_prefix instead of feature'
|
||||||
complete -c git -f -n '__fish_git_using_command feature; and not contains -- finish (commandline -opc)' -a finish -d 'merge and delete the feature branch'
|
complete -c git -f -n '__fish_git_using_command feature; and not contains -- finish (commandline -opc)' -a "finish" -d 'merge and delete the feature branch'
|
||||||
complete -c git -f -n '__fish_git_using_command feature; and contains -- finish (commandline -opc)' -l squash -d 'Run a squash merge'
|
complete -c git -f -n '__fish_git_using_command feature; and contains -- finish (commandline -opc)' -l squash -d 'Run a squash merge'
|
||||||
complete -c git -x -n '__fish_git_using_command feature; and contains -- finish (commandline -opc)' -a '(__fish_git for-each-ref --format="%(refname)" 2>/dev/null | grep "refs/heads/feature")' -d 'name of feature branch'
|
complete -c git -x -n '__fish_git_using_command feature; and contains -- finish (commandline -opc)' -a '(__fish_git for-each-ref --format="%(refname)" 2>/dev/null | grep "refs/heads/feature")' -d 'name of feature branch'
|
||||||
complete -c git -x -n '__fish_git_using_command feature; and not contains -- finish (commandline -opc)' -s r -l remote -a '(__fish_git_unique_remote_branches)' -d 'Setup a remote tracking branch'
|
complete -c git -x -n '__fish_git_using_command feature; and not contains -- finish (commandline -opc)' -s r -l remote -a '(__fish_git_unique_remote_branches)' -d 'Setup a remote tracking branch'
|
||||||
# graft
|
# graft
|
||||||
complete -c git -x -n '__fish_git_using_command graft' -s r -l remote -a '(__fish_git_branches)' -d src-branch-name
|
complete -c git -x -n '__fish_git_using_command graft' -s r -l remote -a '(__fish_git_branches)' -d 'src-branch-name'
|
||||||
complete -c git -x -n '__fish_git_using_command graft' -s r -l remote -a '(__fish_git_branches)' -d dest-branch-name
|
complete -c git -x -n '__fish_git_using_command graft' -s r -l remote -a '(__fish_git_branches)' -d 'dest-branch-name'
|
||||||
# guilt
|
# guilt
|
||||||
complete -c git -f -n '__fish_git_using_command guilt' -s w -l ignore-whitespace -d 'ignore whitespace only changes'
|
complete -c git -f -n '__fish_git_using_command guilt' -s w -l ignore-whitespace -d 'ignore whitespace only changes'
|
||||||
complete -c git -f -n '__fish_git_using_command guilt' -s e -l email -d 'display author emails instead of names'
|
complete -c git -f -n '__fish_git_using_command guilt' -s e -l email -d 'display author emails instead of names'
|
||||||
complete -c git -f -n '__fish_git_using_command guilt' -s d -l debug -d 'output debug information'
|
complete -c git -f -n '__fish_git_using_command guilt' -s d -l debug -d 'output debug information'
|
||||||
complete -c git -f -n '__fish_git_using_command guilt' -s h -d 'output usage information'
|
complete -c git -f -n '__fish_git_using_command guilt' -s h -d 'output usage information'
|
||||||
# ignore
|
# ignore
|
||||||
complete -c git -f -n '__fish_git_using_command ignore' -s l -l local -d 'set context to local gitignore'
|
complete -c git -f -n '__fish_git_using_command ignore' -s l -l local -d 'show local gitignore'
|
||||||
complete -c git -f -n '__fish_git_using_command ignore' -s g -l global -d 'set context to global gitignore'
|
complete -c git -f -n '__fish_git_using_command ignore' -s g -l global -d 'show global gitignore'
|
||||||
complete -c git -f -n '__fish_git_using_command ignore' -s p -l private -d 'set context to private gitignore'
|
complete -c git -f -n '__fish_git_using_command ignore' -s p -l private -d 'show repo gitignore'
|
||||||
complete -c git -f -n '__fish_git_using_command ignore' -s e -l edit -d 'set action to edit'
|
|
||||||
complete -c git -f -n '__fish_git_using_command ignore' -s r -l remove -d 'set action to remove'
|
|
||||||
# ignore-io
|
# ignore-io
|
||||||
function __fish_git_extra_get_ignore_io_types
|
function __fish_git_extra_get_ignore_io_types
|
||||||
# we will first remove every tab spaces, and then append `\t` at the end to remove the default description
|
# we will first remove every tab spaces, and then append `\t` at the end to remove the default description
|
||||||
|
|
@ -181,35 +148,33 @@ complete -c git -x -n '__fish_git_using_command ignore-io' -s s -l search -d 'se
|
||||||
complete -c git -x -n '__fish_git_using_command ignore-io' -s t -l show-update-time -d 'Show the last modified time of ~/.gi_list'
|
complete -c git -x -n '__fish_git_using_command ignore-io' -s t -l show-update-time -d 'Show the last modified time of ~/.gi_list'
|
||||||
complete -c git -x -n '__fish_git_using_command ignore-io' -s u -l update -d 'Update ~/.gi_list'
|
complete -c git -x -n '__fish_git_using_command ignore-io' -s u -l update -d 'Update ~/.gi_list'
|
||||||
# merge-into
|
# merge-into
|
||||||
complete -c git -n '__fish_git_using_command merge-into' -l ff-only -d 'merge only fast-forward'
|
complete -c git -n '__fish_git_using_command merge-into' -l ff-only -d 'merge only fast-forward'
|
||||||
complete -c git -x -n '__fish_git_using_command merge-into' -a '(__fish_git_branches)'
|
complete -c git -x -n '__fish_git_using_command merge-into' -a '(__fish_git_branches)'
|
||||||
# missing
|
# missing
|
||||||
complete -c git -x -n '__fish_git_using_command missing' -a '(__fish_git_branches)'
|
complete -c git -x -n '__fish_git_using_command missing' -a '(__fish_git_branches)'
|
||||||
# rename-file
|
|
||||||
complete -c git -f -n '__fish_git_using_command rename-file' -s h -l help -d 'Show usage information'
|
|
||||||
# squash
|
# squash
|
||||||
complete -c git -x -n '__fish_git_using_command squash' -a '(__fish_git_branches)'
|
complete -c git -x -n '__fish_git_using_command squash' -a '(__fish_git_branches)'
|
||||||
complete -c git -x -n '__fish_git_using_command squash' -l squash-msg -d 'commit with the squashed commit messages'
|
complete -c git -x -n '__fish_git_using_command squash' -l squash-msg -d 'commit with the squashed commit messages'
|
||||||
# stamp
|
# stamp
|
||||||
complete -c git -x -n '__fish_git_using_command stamp' -s r -l replace -d 'replace stamps with same id'
|
complete -c git -x -n '__fish_git_using_command stamp' -s r -l replace -d 'replace stamps with same id'
|
||||||
# standup
|
# standup
|
||||||
complete -c git -x -n '__fish_git_using_command standup' -s a -d 'Specify the author of commits. Use all to specify all authors'
|
complete -c git -x -n '__fish_git_using_command standup' -s a -d 'Specify the author of commits. Use "all" to specify all authors'
|
||||||
complete -c git -x -n '__fish_git_using_command standup' -s m -d 'The depth of recursive directory search'
|
complete -c git -x -n '__fish_git_using_command standup' -s m -d 'The depth of recursive directory search'
|
||||||
complete -c git -x -n '__fish_git_using_command standup' -s d -d 'Show history since N days ago'
|
complete -c git -x -n '__fish_git_using_command standup' -s d -d 'Show history since N days ago'
|
||||||
complete -c git -x -n '__fish_git_using_command standup' -s D -d 'Specify the date format displayed in commit history'
|
complete -c git -x -n '__fish_git_using_command standup' -s D -d 'Specify the date format displayed in commit history'
|
||||||
complete -c git -n '__fish_git_using_command standup' -s f -d 'Fetch commits before showing history'
|
complete -c git -n '__fish_git_using_command standup' -s f -d 'Fetch commits before showing history'
|
||||||
complete -c git -n '__fish_git_using_command standup' -s g -d 'Display GPG signed info'
|
complete -c git -n '__fish_git_using_command standup' -s g -d 'Display GPG signed info'
|
||||||
complete -c git -n '__fish_git_using_command standup' -s h -l help -d 'Display help message'
|
complete -c git -n '__fish_git_using_command standup' -s h -l help -d 'Display help message'
|
||||||
complete -c git -n '__fish_git_using_command standup' -s L -d 'Enable the inclusion of symbolic links'
|
complete -c git -n '__fish_git_using_command standup' -s L -d 'Enable the inclusion of symbolic links'
|
||||||
complete -c git -n '__fish_git_using_command standup' -s B -d 'Display the commits in branch group'
|
complete -c git -n '__fish_git_using_command standup' -s B -d 'Display the commits in branch group'
|
||||||
complete -c git -x -n '__fish_git_using_command standup' -s n -d 'Limit the number of commits displayed per group'
|
complete -c git -x -n '__fish_git_using_command standup' -s n -d 'Limit the number of commits displayed per group'
|
||||||
# summary
|
# summary
|
||||||
complete -c git -n '__fish_git_using_command summary' -l line -d 'summarize with lines rather than commits'
|
complete -c git -n '__fish_git_using_command summary' -l line -d 'summarize with lines rather than commits'
|
||||||
complete -c git -n '__fish_git_using_command summary' -l dedup-by-email -d 'remove duplicate users by the email address'
|
complete -c git -n '__fish_git_using_command summary' -l dedup-by-email -d 'remove duplicate users by the email address'
|
||||||
complete -c git -n '__fish_git_using_command summary' -l no-merges -d 'exclude merge commits'
|
complete -c git -n '__fish_git_using_command summary' -l no-merges -d 'exclude merge commits'
|
||||||
# release
|
# release
|
||||||
complete -c git -x -n '__fish_git_using_command release' -s c -d 'Generates/populates the changelog with all commit message since the last tag'
|
complete -c git -x -n '__fish_git_using_command release' -s c -d 'Generates/populates the changelog with all commit message since the last tag'
|
||||||
complete -c git -x -n '__fish_git_using_command release' -s r -d 'The remote repository that is destination of a push operation'
|
complete -c git -x -n '__fish_git_using_command release' -s r -d 'The "remote" repository that is destination of a push operation'
|
||||||
complete -c git -x -n '__fish_git_using_command release' -s m -d 'use the custom commit information instead of the default message'
|
complete -c git -x -n '__fish_git_using_command release' -s m -d 'use the custom commit information instead of the default message'
|
||||||
complete -c git -x -n '__fish_git_using_command release' -s s -d 'Create a signed and annotated tag'
|
complete -c git -x -n '__fish_git_using_command release' -s s -d 'Create a signed and annotated tag'
|
||||||
complete -c git -x -n '__fish_git_using_command release' -s u -d 'Create a tag, annotated and signed with the given key'
|
complete -c git -x -n '__fish_git_using_command release' -s u -d 'Create a tag, annotated and signed with the given key'
|
||||||
|
|
@ -218,3 +183,5 @@ complete -c git -x -n '__fish_git_using_command release' -l no-empty-commit -d '
|
||||||
# undo
|
# undo
|
||||||
complete -c git -x -n '__fish_git_using_command undo' -s s -l soft -d 'only rolls back the commit but changes remain un-staged'
|
complete -c git -x -n '__fish_git_using_command undo' -s s -l soft -d 'only rolls back the commit but changes remain un-staged'
|
||||||
complete -c git -x -n '__fish_git_using_command undo' -s h -l hard -d 'wipes your commit(s)'
|
complete -c git -x -n '__fish_git_using_command undo' -s h -l hard -d 'wipes your commit(s)'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
is_git_repo() {
|
is_git_repo() {
|
||||||
# --git-dir succeeds for both normal and bare repositories, whereas
|
git rev-parse --show-toplevel > /dev/null 2>&1
|
||||||
# --show-toplevel fails inside a bare repository (it has no working tree).
|
|
||||||
git rev-parse --git-dir > /dev/null 2>&1
|
|
||||||
result=$?
|
result=$?
|
||||||
if test $result != 0; then
|
if test $result != 0; then
|
||||||
>&2 echo 'Not a git repo!'
|
>&2 echo 'Not a git repo!'
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
# reset environment variables that could interfere with normal usage
|
# reset environment variables that could interfere with normal usage
|
||||||
unset -v GREP_OPTIONS
|
export GREP_OPTIONS=
|
||||||
|
|
|
||||||
47
install.cmd
47
install.cmd
|
|
@ -39,34 +39,13 @@ goto :defaultpath
|
||||||
rem remove the last slash
|
rem remove the last slash
|
||||||
SET bindir=%bindir:~0,-1%
|
SET bindir=%bindir:~0,-1%
|
||||||
for %%G in ("%bindir%") do set installdir=%%~dpG
|
for %%G in ("%bindir%") do set installdir=%%~dpG
|
||||||
rem strip a trailing slash so we can inspect the leaf directory name
|
set PREFIX=%installdir%mingw64
|
||||||
if "%installdir:~-1%"=="\" set installdir=%installdir:~0,-1%
|
|
||||||
rem git.exe found under <GitRoot>\mingw64\bin or <GitRoot>\clangarm64\bin
|
|
||||||
rem means installdir already is the architecture directory itself
|
|
||||||
for %%G in ("%installdir%") do set archdir=%%~nxG
|
|
||||||
if /I "%archdir%"=="mingw64" (
|
|
||||||
set PREFIX=%installdir%
|
|
||||||
) else if /I "%archdir%"=="clangarm64" (
|
|
||||||
set PREFIX=%installdir%
|
|
||||||
) else if exist "%installdir%\mingw64" (
|
|
||||||
set PREFIX=%installdir%\mingw64
|
|
||||||
) else if exist "%installdir%\clangarm64" (
|
|
||||||
set PREFIX=%installdir%\clangarm64
|
|
||||||
) else (
|
|
||||||
set PREFIX=%installdir%\mingw64
|
|
||||||
)
|
|
||||||
goto :foundprefix
|
goto :foundprefix
|
||||||
|
|
||||||
:defaultpath
|
:defaultpath
|
||||||
:: default for Git for Windows 2.x
|
:: default for Git for Windows 2.x
|
||||||
if exist "%ProgramFiles%\Git" (
|
if exist "%ProgramFiles%\Git" (
|
||||||
if exist "%ProgramFiles%\Git\mingw64" (
|
set PREFIX=%ProgramFiles%\Git\mingw64
|
||||||
set PREFIX=%ProgramFiles%\Git\mingw64
|
|
||||||
) else if exist "%ProgramFiles%\Git\clangarm64" (
|
|
||||||
set PREFIX=%ProgramFiles%\Git\clangarm64
|
|
||||||
) else (
|
|
||||||
set PREFIX=%ProgramFiles%\Git\mingw64
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
:foundprefix
|
:foundprefix
|
||||||
|
|
@ -76,11 +55,9 @@ IF NOT "%~1"=="" (
|
||||||
REM just supplying the git dir is enough...
|
REM just supplying the git dir is enough...
|
||||||
if exist "%~1\mingw64" (
|
if exist "%~1\mingw64" (
|
||||||
set PREFIX=%~1\mingw64
|
set PREFIX=%~1\mingw64
|
||||||
) else if exist "%~1\clangarm64" (
|
|
||||||
set PREFIX=%~1\clangarm64
|
|
||||||
) else (
|
) else (
|
||||||
echo Using git install path "%~1" as PREFIX, please make sure it's really a
|
echo Using git install path "%~1" as PREFIX, please make sure it's really a
|
||||||
echo path to the mingw64 or clangarm64 directory...
|
echo path to the mingw64 directory...
|
||||||
echo.
|
echo.
|
||||||
SET PREFIX=%~1
|
SET PREFIX=%~1
|
||||||
)
|
)
|
||||||
|
|
@ -95,14 +72,12 @@ set GIT_INSTALL_DIR=!GIT_INSTALL_DIR:"=!
|
||||||
IF %GIT_INSTALL_DIR:~-1%==\ SET GIT_INSTALL_DIR=%GIT_INSTALL_DIR:~0,-1%
|
IF %GIT_INSTALL_DIR:~-1%==\ SET GIT_INSTALL_DIR=%GIT_INSTALL_DIR:~0,-1%
|
||||||
|
|
||||||
if not exist "%GIT_INSTALL_DIR%\mingw64" (
|
if not exist "%GIT_INSTALL_DIR%\mingw64" (
|
||||||
if not exist "%GIT_INSTALL_DIR%\clangarm64" (
|
echo No mingw64 folder found in %GIT_INSTALL_DIR%.
|
||||||
echo No mingw64 or clangarm64 folder found in %GIT_INSTALL_DIR%.
|
echo.
|
||||||
echo.
|
echo Please supply a proper "Git for Windows 2.x" install path:
|
||||||
echo Please supply a proper "Git for Windows 2.x" install path:
|
echo "install.cmd c:\[git-install-path]"
|
||||||
echo "install.cmd c:\[git-install-path]"
|
set ERROR=1
|
||||||
set ERROR=1
|
goto :exit
|
||||||
goto :exit
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
echo Installing to %PREFIX%
|
echo Installing to %PREFIX%
|
||||||
|
|
@ -141,7 +116,7 @@ FOR /R "%GITEXTRAS%\bin" %%i in (*.*) DO (
|
||||||
TYPE "%GITEXTRAS%\helper\reset-env" >> "%PREFIX%\bin\%%~ni"
|
TYPE "%GITEXTRAS%\helper\reset-env" >> "%PREFIX%\bin\%%~ni"
|
||||||
TYPE "%GITEXTRAS%\helper\git-extra-utility" >> "%PREFIX%\bin\%%~ni"
|
TYPE "%GITEXTRAS%\helper\git-extra-utility" >> "%PREFIX%\bin\%%~ni"
|
||||||
TYPE "%GITEXTRAS%\helper\is-git-repo" >> "%PREFIX%\bin\%%~ni"
|
TYPE "%GITEXTRAS%\helper\is-git-repo" >> "%PREFIX%\bin\%%~ni"
|
||||||
|
|
||||||
REM Added /E option for installation fix on Windows 10.0.17134 and higher
|
REM Added /E option for installation fix on Windows 10.0.17134 and higher
|
||||||
MORE /E +2 "%GITEXTRAS%\bin\%%~ni" >> "%PREFIX%\bin\%%~ni"
|
MORE /E +2 "%GITEXTRAS%\bin\%%~ni" >> "%PREFIX%\bin\%%~ni"
|
||||||
)
|
)
|
||||||
|
|
@ -152,7 +127,7 @@ FOR %%i in (%COMMANDS_WITHOUT_REPO%) DO (
|
||||||
ECHO #^^!/usr/bin/env bash > "%PREFIX%\bin\%%i"
|
ECHO #^^!/usr/bin/env bash > "%PREFIX%\bin\%%i"
|
||||||
TYPE "%GITEXTRAS%\helper\reset-env" >> "%PREFIX%\bin\%%i"
|
TYPE "%GITEXTRAS%\helper\reset-env" >> "%PREFIX%\bin\%%i"
|
||||||
TYPE "%GITEXTRAS%\helper\git-extra-utility" >> "%PREFIX%\bin\%%i"
|
TYPE "%GITEXTRAS%\helper\git-extra-utility" >> "%PREFIX%\bin\%%i"
|
||||||
|
|
||||||
REM Added /E option for installation fix on Windows 10.0.17134 and higher
|
REM Added /E option for installation fix on Windows 10.0.17134 and higher
|
||||||
MORE /E +2 "%GITEXTRAS%\bin\%%i" >> "%PREFIX%\bin\%%i"
|
MORE /E +2 "%GITEXTRAS%\bin\%%i" >> "%PREFIX%\bin\%%i"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
\fBgit\-abort\fR
|
\fBgit\-abort\fR
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
Abort current git revert, rebase, merge or cherry\-pick process\.
|
Abort current git rebase, merge or cherry\-pick process\.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
There are no options, it just aborts current operation\.
|
There are no options, it just aborts current operation\.
|
||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
||||||
|
|
||||||
<p> Abort current git revert, rebase, merge or cherry-pick process.</p>
|
<p> Abort current git rebase, merge or cherry-pick process.</p>
|
||||||
|
|
||||||
<h2 id="OPTIONS">OPTIONS</h2>
|
<h2 id="OPTIONS">OPTIONS</h2>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ git-abort(1) -- Abort current git operation
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
|
|
||||||
Abort current git revert, rebase, merge or cherry-pick process.
|
Abort current git rebase, merge or cherry-pick process.
|
||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
.\" generated with Ronn-NG/v0.9.1
|
.\" generated with Ronn-NG/v0.9.1
|
||||||
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
||||||
.TH "GIT\-ALIAS" "1" "September 2024" "" "Git Extras"
|
.TH "GIT\-ALIAS" "1" "August 2021" "" "Git Extras"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBgit\-alias\fR \- Define, search and show aliases
|
\fBgit\-alias\fR \- Define, search and show aliases
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
|
|
@ -9,30 +9,9 @@
|
||||||
\fBgit\-alias\fR <search\-pattern>
|
\fBgit\-alias\fR <search\-pattern>
|
||||||
.br
|
.br
|
||||||
\fBgit\-alias\fR <alias\-name> <command>
|
\fBgit\-alias\fR <alias\-name> <command>
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-global]
|
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-local]
|
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-global] <search\-pattern>
|
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-local] <search\-pattern>
|
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-global] <alias\-name> <command>
|
|
||||||
.br
|
|
||||||
\fBgit\-alias\fR [\-\-local] <alias\-name> <command>
|
|
||||||
.br
|
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
List all aliases, show one alias, or set one (global or local) alias\.
|
List all aliases, show one alias, or set one (global) alias\.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
\-\-global
|
|
||||||
.P
|
|
||||||
Show or create alias in the system config
|
|
||||||
.P
|
|
||||||
\-\-local
|
|
||||||
.P
|
|
||||||
Show or create alias in the repository config
|
|
||||||
.P
|
|
||||||
<search\-pattern>
|
<search\-pattern>
|
||||||
.P
|
.P
|
||||||
The pattern used to search aliases\.
|
The pattern used to search aliases\.
|
||||||
|
|
@ -67,8 +46,8 @@ $ git alias
|
||||||
s = status
|
s = status
|
||||||
amend = commit \-\-amend
|
amend = commit \-\-amend
|
||||||
rank = shortlog \-sn \-\-no\-merges
|
rank = shortlog \-sn \-\-no\-merges
|
||||||
whatis = show \-s \-\-pretty='tformat:%h (%s, %ad)' \-\-date=short
|
whatis = show \-s \-\-pretty=\'tformat:%h (%s, %ad)\' \-\-date=short
|
||||||
whois = !sh \-c 'git log \-i \-1 \-\-pretty="format:%an <%ae>
|
whois = !sh \-c \'git log \-i \-1 \-\-pretty="format:%an <%ae>
|
||||||
.fi
|
.fi
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
.SH "AUTHOR"
|
.SH "AUTHOR"
|
||||||
|
|
|
||||||
|
|
@ -77,30 +77,16 @@
|
||||||
</p>
|
</p>
|
||||||
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
||||||
|
|
||||||
<p><code>git-alias</code> <br>
|
<p><code>git-alias</code><br>
|
||||||
<code>git-alias</code> <search-pattern> <br>
|
<code>git-alias</code> <search-pattern><br>
|
||||||
<code>git-alias</code> <alias-name> <command> <br>
|
<code>git-alias</code> <alias-name> <command></p>
|
||||||
<code>git-alias</code> [--global] <br>
|
|
||||||
<code>git-alias</code> [--local] <br>
|
|
||||||
<code>git-alias</code> [--global] <search-pattern> <br>
|
|
||||||
<code>git-alias</code> [--local] <search-pattern> <br>
|
|
||||||
<code>git-alias</code> [--global] <alias-name> <command> <br>
|
|
||||||
<code>git-alias</code> [--local] <alias-name> <command> <br></p>
|
|
||||||
|
|
||||||
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
||||||
|
|
||||||
<p>List all aliases, show one alias, or set one (global or local) alias.</p>
|
<p>List all aliases, show one alias, or set one (global) alias.</p>
|
||||||
|
|
||||||
<h2 id="OPTIONS">OPTIONS</h2>
|
<h2 id="OPTIONS">OPTIONS</h2>
|
||||||
|
|
||||||
<p>--global</p>
|
|
||||||
|
|
||||||
<p>Show or create alias in the system config</p>
|
|
||||||
|
|
||||||
<p>--local</p>
|
|
||||||
|
|
||||||
<p>Show or create alias in the repository config</p>
|
|
||||||
|
|
||||||
<p><search-pattern></p>
|
<p><search-pattern></p>
|
||||||
|
|
||||||
<p>The pattern used to search aliases.</p>
|
<p>The pattern used to search aliases.</p>
|
||||||
|
|
@ -150,7 +136,7 @@ whois = !sh -c 'git log -i -1 --pretty="format:%an <%ae>
|
||||||
|
|
||||||
<ol class='man-decor man-foot man foot'>
|
<ol class='man-decor man-foot man foot'>
|
||||||
<li class='tl'></li>
|
<li class='tl'></li>
|
||||||
<li class='tc'>September 2024</li>
|
<li class='tc'>August 2021</li>
|
||||||
<li class='tr'>git-alias(1)</li>
|
<li class='tr'>git-alias(1)</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue