@@ -1,9 +1,9 @@ | |||||
__gitup__ (the _git-repo-updater_) | __gitup__ (the _git-repo-updater_) | ||||
gitup is a tool designed to pull to a large number of git repositories at once. | |||||
It is smart enough to ignore repos with dirty working directories, and provides | |||||
a (hopefully) great way to get everything up-to-date for those short periods of | |||||
internet access between long periods of none. | |||||
gitup is a tool designed to update a large number of git repositories at once. | |||||
It is smart enough to handle multiple remotes, branches, dirty working | |||||
directories, and more, hopefully providing a great way to get everything | |||||
up-to-date for short periods of internet access between long periods of none. | |||||
gitup should work on OS X, Linux, and Windows. You should have the latest | gitup should work on OS X, Linux, and Windows. You should have the latest | ||||
version of git and at least Python 2.7 installed. | version of git and at least Python 2.7 installed. | ||||
@@ -40,9 +40,8 @@ For example: | |||||
gitup ~/repos/foo ~/repos/bar ~/repos/baz | gitup ~/repos/foo ~/repos/bar ~/repos/baz | ||||
will automatically pull to the `foo`, `bar`, and `baz` git repositories if | |||||
their working directories are clean (to avoid merge conflicts). Additionally, | |||||
you can just type: | |||||
will automatically pull to the `foo`, `bar`, and `baz` git repositories. | |||||
Additionally, you can just type: | |||||
gitup ~/repos | gitup ~/repos | ||||
@@ -53,15 +52,15 @@ To add a bookmark (or bookmarks), either of these will work: | |||||
gitup --add ~/repos/foo ~/repos/bar ~/repos/baz | gitup --add ~/repos/foo ~/repos/bar ~/repos/baz | ||||
gitup --add ~/repos | gitup --add ~/repos | ||||
Then, to update (pull to) all of your bookmarks, just run gitup without args: | |||||
Then, to update all of your bookmarks, just run gitup without args: | |||||
gitup | gitup | ||||
Deleting a bookmark is as easy as adding one: | |||||
Delete a bookmark: | |||||
gitup --delete ~/repos | gitup --delete ~/repos | ||||
Want to view your current bookmarks? Simple: | |||||
View your current bookmarks: | |||||
gitup --list | gitup --list | ||||
@@ -72,10 +71,18 @@ You can mix and match bookmarks and command arguments: | |||||
gitup # update 'foo' and 'bar' only | gitup # update 'foo' and 'bar' only | ||||
gitup ~/repos/baz --update # update all three! | gitup ~/repos/baz --update # update all three! | ||||
Want to update all git repositories in your current directory? | |||||
Update all git repositories in your current directory: | |||||
gitup . | gitup . | ||||
By default, gitup will fetch all remotes in a repository. Pass `--current-only` | |||||
(or `-c`) to make it only fetch the remote tracked by the current branch. | |||||
gitup will _merge_ upstream branches by default unless `pull.rebase` or | |||||
`branch.<name>.rebase` is specified in git's config. Pass `--rebase` or `-r` to | |||||
make it always _rebase_ (like doing `git pull --rebase=preserve`). Pass | |||||
`--merge` or `-m` to make it always merge. | |||||
For a list of all command arguments and abbreviations: | For a list of all command arguments and abbreviations: | ||||
gitup --help | gitup --help | ||||
@@ -36,7 +36,7 @@ def main(): | |||||
'-u', '--update', action="store_true", help="""update all bookmarks | '-u', '--update', action="store_true", help="""update all bookmarks | ||||
(default behavior when called without arguments)""") | (default behavior when called without arguments)""") | ||||
group_u.add_argument( | group_u.add_argument( | ||||
'-c', '--current-only', action="store_true", help="""only pull the | |||||
'-c', '--current-only', action="store_true", help="""only fetch the | |||||
remote tracked by the current branch instead of all remotes""") | remote tracked by the current branch instead of all remotes""") | ||||
rebase_or_merge.add_argument( | rebase_or_merge.add_argument( | ||||
'-r', '--rebase', action="store_true", help="""always rebase upstream | '-r', '--rebase', action="store_true", help="""always rebase upstream | ||||
@@ -117,9 +117,11 @@ def _rebase(repo, name): | |||||
"""Rebase the current HEAD of *repo* onto the branch *name*.""" | """Rebase the current HEAD of *repo* onto the branch *name*.""" | ||||
print(GREEN + "rebasing...", end="") | print(GREEN + "rebasing...", end="") | ||||
try: | try: | ||||
res = repo.git.rebase(name) | |||||
res = repo.git.rebase(name, "--preserve-merges") | |||||
except exc.GitCommandError as err: | except exc.GitCommandError as err: | ||||
msg = err.stderr.replace("\n", " ").strip() | msg = err.stderr.replace("\n", " ").strip() | ||||
if not msg.endswith("."): | |||||
msg += "." | |||||
if "unstaged changes" in msg: | if "unstaged changes" in msg: | ||||
print(RED + " error:", "unstaged changes.") | print(RED + " error:", "unstaged changes.") | ||||
elif "uncommitted changes" in msg: | elif "uncommitted changes" in msg: | ||||
@@ -129,7 +131,8 @@ def _rebase(repo, name): | |||||
repo.git.rebase("--abort") | repo.git.rebase("--abort") | ||||
except exc.GitCommandError: | except exc.GitCommandError: | ||||
pass | pass | ||||
print(RED + " error:", msg if msg else "rebase conflict.") | |||||
print(RED + " error:", msg if msg else "rebase conflict.", | |||||
"Aborted.") | |||||
else: | else: | ||||
print("\b" * 6 + " " * 6 + "\b" * 6 + GREEN + "ed", end=".\n") | print("\b" * 6 + " " * 6 + "\b" * 6 + GREEN + "ed", end=".\n") | ||||
@@ -140,6 +143,8 @@ def _merge(repo, name): | |||||
repo.git.merge(name) | repo.git.merge(name) | ||||
except exc.GitCommandError as err: | except exc.GitCommandError as err: | ||||
msg = err.stderr.replace("\n", " ").strip() | msg = err.stderr.replace("\n", " ").strip() | ||||
if not msg.endswith("."): | |||||
msg += "." | |||||
if "local changes" in msg and "would be overwritten" in msg: | if "local changes" in msg and "would be overwritten" in msg: | ||||
print(RED + " error:", "uncommitted changes.") | print(RED + " error:", "uncommitted changes.") | ||||
else: | else: | ||||
@@ -147,7 +152,8 @@ def _merge(repo, name): | |||||
repo.git.merge("--abort") | repo.git.merge("--abort") | ||||
except exc.GitCommandError: | except exc.GitCommandError: | ||||
pass | pass | ||||
print(RED + " error:", msg if msg else "merge conflict.") | |||||
print(RED + " error:", msg if msg else "merge conflict.", | |||||
"Aborted.") | |||||
else: | else: | ||||
print("\b" * 6 + " " * 6 + "\b" * 6 + GREEN + "ed", end=".\n") | print("\b" * 6 + " " * 6 + "\b" * 6 + GREEN + "ed", end=".\n") | ||||