More tweaks. I am more or less happy now.
This commit is contained in:
parent
01775362b3
commit
617eeb2c71
31
README.md
31
README.md
@ -1,29 +1,18 @@
|
|||||||
# git-tidy
|
# git-tidy
|
||||||
|
|
||||||
Have you ever come back to a git repo after a while, started developing, and
|
I wrote this utility to save myself some repetitive typing, because I often come
|
||||||
then realised you weren't on the main branch, or your branch was missing the
|
back to a repo after a while of not using it, and in the meanwhile a remote may
|
||||||
latest changes, so you ended up with merge conflicts?
|
have moved on or I'm not sure what state it's in.
|
||||||
|
|
||||||
Or have you ever finished working on a feature, completed a pull-request online,
|
So this gets it cleaned up relatively quickly.
|
||||||
and wanted an easy way to clean up your local repo from all the unused
|
|
||||||
references that have accumulated themselves?
|
|
||||||
|
|
||||||
Then `git-tidy` is for you!
|
It's more or less the equivalent of
|
||||||
|
|
||||||
This is a simple Python script which you can install by copying (or symlinking)
|
|
||||||
anywhere on your path (I recommend ~/bin/, but something like /usr/local/bin/
|
|
||||||
would also work).
|
|
||||||
|
|
||||||
Entering
|
|
||||||
```bash
|
```bash
|
||||||
git tidy
|
git checkout main
|
||||||
|
git fetch --all --purge # purge is to delete unnecessary remote refs
|
||||||
|
git merge origin/main main --ff-only
|
||||||
|
git branch --merged | grep -v main | xargs git branch -d
|
||||||
```
|
```
|
||||||
at the terminal will:
|
|
||||||
- Check out the default branch, usually `main`
|
|
||||||
- if this is not configured, it will try to figure out what it should be,
|
|
||||||
- Pull to make sure that you're up-to-date with the default branch,
|
|
||||||
- Delete all branches that have already been merged into the default, and,
|
|
||||||
- Delete all references which have been removed from the remote as well,
|
|
||||||
|
|
||||||
leaving you with a pristine, tidy repository in order to continue your
|
with some extra convenience and (I hope) safety features.
|
||||||
development.
|
|
||||||
|
65
git-tidy.py
65
git-tidy.py
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
# You should have received a copy of the GNU General Public License along with git-tidy. If not, see
|
# You should have received a copy of the GNU General Public License along with git-tidy. If not, see
|
||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
"""git-tidy module."""
|
"""git-tidy utility."""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@ -54,11 +54,22 @@ def run(command: Union[List[str], str]) -> Tuple[int, str]:
|
|||||||
|
|
||||||
|
|
||||||
def get_default_branch() -> str:
|
def get_default_branch() -> str:
|
||||||
"""Return the name of the repo's default branch."""
|
"""Return the name of the repo's default branch.
|
||||||
|
|
||||||
|
First try the config, if that doesn't work, check existing branches for
|
||||||
|
some common defaults. If there aren't any or they're ambiguous, ask the
|
||||||
|
user.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
The name of the default branch with which we'll work for the rest of
|
||||||
|
the exercise.
|
||||||
|
"""
|
||||||
returncode, configured_default_branch = run(["git", "config", "--get", "--local", "tidy.defaultbranch"])
|
returncode, configured_default_branch = run(["git", "config", "--get", "--local", "tidy.defaultbranch"])
|
||||||
if returncode == 128:
|
if returncode == 128:
|
||||||
# The --local flag caused this to fail because we're not in a git repository.
|
# The --local flag caused this to fail because we're not in a git repository.
|
||||||
print(configured_default_branch, file=sys.stderr)
|
print("fatal: not inside a repository", file=sys.stderr)
|
||||||
sys.exit(returncode)
|
sys.exit(returncode)
|
||||||
|
|
||||||
# If we're in a repository, we need a list of branches, either as a
|
# If we're in a repository, we need a list of branches, either as a
|
||||||
@ -77,12 +88,12 @@ def get_default_branch() -> str:
|
|||||||
return configured_default_branch
|
return configured_default_branch
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"{configured_default_branch} configured as defauly branch for tidying purposes, but it doesn't exist!",
|
f"{configured_default_branch} configured as default branch for tidying purposes, but it doesn't exist! "
|
||||||
|
"Attempting to reconfigure....",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
# TODO: There is probably a clean way to fix this.
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
|
else:
|
||||||
print("No default branch for git-tidy configured, will try to figure out which to use...")
|
print("No default branch for git-tidy configured, will try to figure out which to use...")
|
||||||
|
|
||||||
candidates = []
|
candidates = []
|
||||||
@ -94,27 +105,24 @@ def get_default_branch() -> str:
|
|||||||
|
|
||||||
if len(candidates) == 1:
|
if len(candidates) == 1:
|
||||||
# Only one branch name matches, so we'll go with that one.
|
# Only one branch name matches, so we'll go with that one.
|
||||||
|
print(f"Using branch {candidates[0]}...")
|
||||||
run(["git", "config", "--add", "tidy.defaultbranch", candidates[0]])
|
run(["git", "config", "--add", "tidy.defaultbranch", candidates[0]])
|
||||||
return candidates[0]
|
return candidates[0]
|
||||||
|
|
||||||
if len(candidates) == 0:
|
# If there's no clear default, let the user select which one to use:
|
||||||
print("No candidate branches!", file=sys.stderr)
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# If we don't have one or zero, which do we have?
|
|
||||||
selection = -1
|
selection = -1
|
||||||
while (selection < 0) or (selection >= len(candidates)):
|
while (selection < 0) or (selection >= len(candidates)):
|
||||||
print(
|
print("Unable to determine default branch automatically. Please select one:")
|
||||||
f"{'Several' if len(candidates) > 1 else 'No'} potential default branch candidates found. "
|
for n, branch in enumerate(branch_list):
|
||||||
"Please select one:"
|
print(f"{n}: {branch}")
|
||||||
)
|
|
||||||
for n, candidate in enumerate(candidates):
|
|
||||||
print(f"{n}: {candidate}")
|
|
||||||
|
|
||||||
# TODO: This breaks if the user is stupid and doesn't input an int.
|
raw_input = input("Which to choose?")
|
||||||
selection = int(input("Which to choose?"))
|
try:
|
||||||
|
selection = int(raw_input)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
return candidates[selection]
|
return branch_list[selection]
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@ -125,14 +133,19 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# Check which remote it's configured with.
|
# Check which remote it's configured with.
|
||||||
_, remote = run(["git", "config", "--get", f"branch.{default_branch}.remote"])
|
_, remote = run(["git", "config", "--get", f"branch.{default_branch}.remote"])
|
||||||
|
print(f"{default_branch} is connected to {remote}")
|
||||||
print(f"{default_branch} is configured for remote {remote}")
|
|
||||||
|
|
||||||
# Get latest changes from remote, clear up unnecessary stuff.
|
# Get latest changes from remote, clear up unnecessary stuff.
|
||||||
run(["git", "fetch", "--all", "--prune"])
|
returncode, output = run(["git", "fetch", "--all", "--prune"])
|
||||||
run(
|
if returncode != 0: # possibly a problem in contacting the remote?
|
||||||
["git", "merge", "--ff-only", f"{remote}/{default_branch}", default_branch]
|
print(output, file=sys.stderr)
|
||||||
) # TODO: Handle what happens if the ff fails.
|
sys.exit(returncode)
|
||||||
|
print(output) # I like to see what `git fetch` has accomplished.
|
||||||
|
|
||||||
|
returncode, output = run(["git", "merge", "--ff-only", f"{remote}/{default_branch}", default_branch])
|
||||||
|
if returncode != 0: # Probably fast-forwarding won't work.
|
||||||
|
print(output, file=sys.stderr)
|
||||||
|
sys.exit(returncode)
|
||||||
|
|
||||||
# Check which branches are `--merged` and clean them up.
|
# Check which branches are `--merged` and clean them up.
|
||||||
_, merged_branches_raw = run(["git", "branch", "--merged"])
|
_, merged_branches_raw = run(["git", "branch", "--merged"])
|
||||||
|
Loading…
Reference in New Issue
Block a user