Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Oh My Zsh
Commits
05e2956d
Unverified
Commit
05e2956d
authored
Nov 26, 2020
by
Marc Cornellà
Committed by
GitHub
Nov 26, 2020
Browse files
fix(git-auto-fetch): background `git-fetch-all` and other fixes (#9468)
parent
d8888719
Changes
2
Show whitespace changes
Inline
Side-by-side
plugins/git-auto-fetch/README.md
View file @
05e2956d
# Git auto-fetch
Automatically fetches all changes from all remotes while you are working in git-initialized directory.
Automatically fetches all changes from all remotes while you are working in
a
git-initialized directory.
#### Usage
Add
`git-auto-fetch`
to the plugins array in your zshrc file:
To use it, add
`git-auto-fetch`
to the plugins array in your zshrc file:
```
shell
plugins
=(
... git-auto-fetch
)
```
Every time you launch a command in your shell all remotes will be fetched in background.
By default autofetch will be triggered only if last fetch was done at least 60 seconds ago.
You can change fetch interval in your .zshrc:
```
GIT_AUTO_FETCH_INTERVAL=1200 #in seconds
## Usage
Every time the command prompt is shown all remotes will be fetched in the background. By default,
`git-auto-fetch`
will be triggered only if the last auto-fetch was done at least 60 seconds ago.
You can change the fetch interval in your .zshrc:
```
sh
GIT_AUTO_FETCH_INTERVAL
=
1200
# in seconds
```
Log of
`git fetch --all`
will be saved into
`.git/FETCH_LOG`
A log of
`git fetch --all`
will be saved in
`.git/FETCH_LOG`
.
## Toggle auto-fetch per folder
#### Toggle auto fetch per folder
If you are using mobile connection or for any other reason you can disable git-auto-fetch
for any folder:
If you are using a mobile connection or for any other reason you can disable git-auto-fetch
for any folder:
```
shell
$
cd
to/your/project
...
...
@@ -29,3 +32,19 @@ disabled
$
git-auto-fetch
enabled
```
## Caveats
Automatically fetching all changes defeats the purpose of
`git push --force-with-lease`
,
and makes it behave like
`git push --force`
in some cases. For example:
Consider that you made some changes and possibly rebased some stuff, which means you'll
need to use
`--force-with-lease`
to overwrite the remote history of a branch. Between the
time when you make the changes (maybe do a
`git log`
) and the time when you
`git push`
,
it's possible that someone else updates the branch you're working on.
If
`git-auto-fetch`
triggers then, you'll have fetched the remote changes without knowing
it, and even though you're running the push with
`--force-with-lease`
, git will overwrite
the recent changes because you already have them in your local repository. The
[
`git push --force-with-lease` docs
](
https://git-scm.com/docs/git-push
)
talk about possible
solutions to this problem.
plugins/git-auto-fetch/git-auto-fetch.plugin.zsh
View file @
05e2956d
GIT_AUTO_FETCH_INTERVAL
=
${
GIT_AUTO_FETCH_INTERVAL
:
=60
}
# Default auto-fetch interval: 60 seconds
:
${
GIT_AUTO_FETCH_INTERVAL
:
=60
}
# Necessary for the git-fetch-all function
zmodload zsh/datetime zsh/stat
function
git-fetch-all
{
(
`
command
git rev-parse
--is-inside-work-tree
2>/dev/null
`
&&
dir
=
`
command
git rev-parse
--git-dir
`
&&
[[
!
-f
$dir
/NO_AUTO_FETCH
]]
&&
((
`
date
+%s
`
-
`
date
-r
$dir
/FETCH_LOG +%s 2>/dev/null
||
echo
0
`
>
$GIT_AUTO_FETCH_INTERVAL
))
&&
(
# Get git root directory
if
!
gitdir
=
"
$(
command
git rev-parse
--git-dir
2>/dev/null
)
"
;
then
return
0
fi
# Do nothing if auto-fetch disabled
if
[[
-z
"
$gitdir
"
||
-f
"
$gitdir
/NO_AUTO_FETCH"
]]
;
then
return
0
fi
# Get time (seconds) when auto-fetch was last run
lastrun
=
"
$(
zstat +mtime
"
$gitdir
/FETCH_LOG"
2>/dev/null
||
echo
0
)
"
# Do nothing if not enough time has passed since last auto-fetch
if
((
EPOCHSECONDS - lastrun <
$GIT_AUTO_FETCH_INTERVAL
))
;
then
return
0
fi
# Fetch all remotes (avoid ssh passphrase prompt)
GIT_SSH_COMMAND
=
"command ssh -o BatchMode=yes"
\
command
git fetch
--all
2>/dev/null &>!
$dir
/FETCH_LOG &
)
command
git fetch
--all
2>/dev/null &>!
"
$gitdir
/FETCH_LOG"
)
&|
}
function
git-auto-fetch
{
`
command
git rev-parse
--is-inside-work-tree
2>/dev/null
`
||
return
guard
=
"
`
command
git rev-parse
--
git-dir
`
/NO_AUTO_FETCH"
# Do nothing if not in a git repository
command
git rev-parse
--
is-inside-work-tree
&>/dev/null
||
return
0
(
rm
$guard
2>/dev/null
&&
echo
"
${
fg_bold
[green]
}
enabled
${
reset_color
}
"
)
||
(
touch
$guard
&&
echo
"
${
fg_bold
[red]
}
disabled
${
reset_color
}
"
)
# Remove or create guard file depending on its existence
local
guard
=
"
$(
command
git rev-parse
--git-dir
)
/NO_AUTO_FETCH"
if
[[
-f
"
$guard
"
]]
;
then
command rm
"
$guard
"
&&
echo
"
${
fg_bold
[green]
}
enabled
${
reset_color
}
"
else
command touch
"
$guard
"
&&
echo
"
${
fg_bold
[red]
}
disabled
${
reset_color
}
"
fi
}
# Override zle-line-init if it exists
if
((
$+
functions[zle-line-init]
))
;
then
eval
"override-git-auto-fetch-
$(
declare
-f
zle-line-init
)
"
# zle-line-init widget (don't redefine if already defined)
((
!
${
+functions[_git-auto-fetch_zle-line-init]
}
))
||
return
0
function
zle-line-init
()
{
case
"
$widgets
[zle-line-init]"
in
# Simply define the function if zle-line-init doesn't yet exist
builtin
|
""
)
function
_git-auto-fetch_zle-line-init
()
{
git-fetch-all
override-git-auto-fetch-zle-line-init
}
else
function
zle-line-init
()
{
}
;;
# Override the current zle-line-init widget, calling the old one
user:
*
)
zle
-N
_git-auto-fetch_orig_zle-line-init
"
${
widgets
[zle-line-init]#user
:
}
"
function
_git-auto-fetch_
zle-line-init
()
{
git-fetch-all
}
fi
zle _git-auto-fetch_orig_zle-line-init
--
"
$@
"
}
;;
esac
zle
-N
zle-line-init
zle
-N
zle-line-init
_git-auto-fetch_zle-line-init
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment