Auto-sync from catchthesethighs
This commit is contained in:
@@ -20,8 +20,7 @@ set -e
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
DOTFILES_CONF="${SCRIPT_DIR}/../dotfiles.conf"
|
DOTFILES_CONF="$HOME/.dotfiles/dotfiles.conf"
|
||||||
[[ -f "$DOTFILES_CONF" ]] || DOTFILES_CONF="$HOME/.dotfiles/dotfiles.conf"
|
|
||||||
|
|
||||||
if [[ -f "$DOTFILES_CONF" ]]; then
|
if [[ -f "$DOTFILES_CONF" ]]; then
|
||||||
source "$DOTFILES_CONF"
|
source "$DOTFILES_CONF"
|
||||||
@@ -64,24 +63,24 @@ log_sync() {
|
|||||||
|
|
||||||
get_local_status() {
|
get_local_status() {
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
local status=""
|
local status=""
|
||||||
local ahead=0
|
local ahead=0
|
||||||
local behind=0
|
local behind=0
|
||||||
local modified=0
|
local modified=0
|
||||||
local untracked=0
|
local untracked=0
|
||||||
|
|
||||||
# Fetch quietly
|
# Fetch quietly
|
||||||
git fetch origin --quiet 2>/dev/null || true
|
git fetch origin --quiet 2>/dev/null || true
|
||||||
|
|
||||||
# Count commits ahead/behind
|
# Count commits ahead/behind
|
||||||
ahead=$(git rev-list HEAD..origin/${DOTFILES_BRANCH} --count 2>/dev/null || echo 0)
|
ahead=$(git rev-list HEAD..origin/${DOTFILES_BRANCH} --count 2>/dev/null || echo 0)
|
||||||
behind=$(git rev-list origin/${DOTFILES_BRANCH}..HEAD --count 2>/dev/null || echo 0)
|
behind=$(git rev-list origin/${DOTFILES_BRANCH}..HEAD --count 2>/dev/null || echo 0)
|
||||||
|
|
||||||
# Count modified and untracked
|
# Count modified and untracked
|
||||||
modified=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
|
modified=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
|
||||||
untracked=$(git ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ')
|
untracked=$(git ls-files --others --exclude-standard 2>/dev/null | wc -l | tr -d ' ')
|
||||||
|
|
||||||
echo "$ahead|$behind|$modified|$untracked"
|
echo "$ahead|$behind|$modified|$untracked"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,18 +102,18 @@ has_remote_changes() {
|
|||||||
|
|
||||||
show_status() {
|
show_status() {
|
||||||
print_header
|
print_header
|
||||||
|
|
||||||
echo -e "${CYAN}Machine:${NC} $HOSTNAME"
|
echo -e "${CYAN}Machine:${NC} $HOSTNAME"
|
||||||
echo -e "${CYAN}Branch:${NC} $DOTFILES_BRANCH"
|
echo -e "${CYAN}Branch:${NC} $DOTFILES_BRANCH"
|
||||||
echo -e "${CYAN}Path:${NC} $DOTFILES_DIR"
|
echo -e "${CYAN}Path:${NC} $DOTFILES_DIR"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
IFS='|' read -r behind ahead modified untracked <<< "$(get_local_status)"
|
IFS='|' read -r behind ahead modified untracked <<< "$(get_local_status)"
|
||||||
|
|
||||||
echo -e "${CYAN}Status:${NC}"
|
echo -e "${CYAN}Status:${NC}"
|
||||||
|
|
||||||
# Remote status
|
# Remote status
|
||||||
if [[ $behind -gt 0 ]]; then
|
if [[ $behind -gt 0 ]]; then
|
||||||
echo -e " ${YELLOW}↓${NC} $behind commit(s) behind remote"
|
echo -e " ${YELLOW}↓${NC} $behind commit(s) behind remote"
|
||||||
@@ -123,27 +122,27 @@ show_status() {
|
|||||||
else
|
else
|
||||||
echo -e " ${GREEN}✓${NC} In sync with remote"
|
echo -e " ${GREEN}✓${NC} In sync with remote"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Local changes
|
# Local changes
|
||||||
if [[ $modified -gt 0 ]]; then
|
if [[ $modified -gt 0 ]]; then
|
||||||
echo -e " ${YELLOW}●${NC} $modified modified file(s)"
|
echo -e " ${YELLOW}●${NC} $modified modified file(s)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $untracked -gt 0 ]]; then
|
if [[ $untracked -gt 0 ]]; then
|
||||||
echo -e " ${YELLOW}+${NC} $untracked untracked file(s)"
|
echo -e " ${YELLOW}+${NC} $untracked untracked file(s)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $modified -eq 0 && $untracked -eq 0 ]]; then
|
if [[ $modified -eq 0 && $untracked -eq 0 ]]; then
|
||||||
echo -e " ${GREEN}✓${NC} Working directory clean"
|
echo -e " ${GREEN}✓${NC} Working directory clean"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show recent changes
|
# Show recent changes
|
||||||
echo
|
echo
|
||||||
echo -e "${CYAN}Recent changes:${NC}"
|
echo -e "${CYAN}Recent changes:${NC}"
|
||||||
git log --oneline -5 2>/dev/null | while read -r line; do
|
git log --oneline -5 2>/dev/null | while read -r line; do
|
||||||
echo -e " ${DIM}$line${NC}"
|
echo -e " ${DIM}$line${NC}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Show modified files
|
# Show modified files
|
||||||
if [[ $modified -gt 0 || $untracked -gt 0 ]]; then
|
if [[ $modified -gt 0 || $untracked -gt 0 ]]; then
|
||||||
echo
|
echo
|
||||||
@@ -154,7 +153,7 @@ show_status() {
|
|||||||
local total=$((modified + untracked))
|
local total=$((modified + untracked))
|
||||||
[[ $total -gt 10 ]] && echo -e " ${DIM}... and $((total - 10)) more${NC}"
|
[[ $total -gt 10 ]] && echo -e " ${DIM}... and $((total - 10)) more${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show last sync
|
# Show last sync
|
||||||
if [[ -f "$SYNC_STATE_FILE" ]]; then
|
if [[ -f "$SYNC_STATE_FILE" ]]; then
|
||||||
echo
|
echo
|
||||||
@@ -165,31 +164,31 @@ show_status() {
|
|||||||
|
|
||||||
do_push() {
|
do_push() {
|
||||||
local message="${1:-Auto-sync from $HOSTNAME}"
|
local message="${1:-Auto-sync from $HOSTNAME}"
|
||||||
|
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
if ! has_local_changes; then
|
if ! has_local_changes; then
|
||||||
echo -e "${GREEN}✓${NC} No local changes to push"
|
echo -e "${GREEN}✓${NC} No local changes to push"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${BLUE}==>${NC} Pushing local changes..."
|
echo -e "${BLUE}==>${NC} Pushing local changes..."
|
||||||
|
|
||||||
# Stage all changes
|
# Stage all changes
|
||||||
git add -A
|
git add -A
|
||||||
|
|
||||||
# Show what we're committing
|
# Show what we're committing
|
||||||
echo -e "${CYAN}Changes:${NC}"
|
echo -e "${CYAN}Changes:${NC}"
|
||||||
git diff --cached --stat | head -10
|
git diff --cached --stat | head -10
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Commit
|
# Commit
|
||||||
git commit -m "$message" || {
|
git commit -m "$message" || {
|
||||||
echo -e "${YELLOW}⚠${NC} Nothing to commit"
|
echo -e "${YELLOW}⚠${NC} Nothing to commit"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Push
|
# Push
|
||||||
if git push origin "$DOTFILES_BRANCH"; then
|
if git push origin "$DOTFILES_BRANCH"; then
|
||||||
echo -e "${GREEN}✓${NC} Changes pushed successfully"
|
echo -e "${GREEN}✓${NC} Changes pushed successfully"
|
||||||
@@ -203,9 +202,9 @@ do_push() {
|
|||||||
|
|
||||||
do_pull() {
|
do_pull() {
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
echo -e "${BLUE}==>${NC} Pulling remote changes..."
|
echo -e "${BLUE}==>${NC} Pulling remote changes..."
|
||||||
|
|
||||||
# Stash local changes if any
|
# Stash local changes if any
|
||||||
local had_changes=false
|
local had_changes=false
|
||||||
if has_local_changes; then
|
if has_local_changes; then
|
||||||
@@ -213,13 +212,13 @@ do_pull() {
|
|||||||
git stash push -m "Auto-stash before pull"
|
git stash push -m "Auto-stash before pull"
|
||||||
had_changes=true
|
had_changes=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Pull
|
# Pull
|
||||||
if git pull origin "$DOTFILES_BRANCH"; then
|
if git pull origin "$DOTFILES_BRANCH"; then
|
||||||
echo -e "${GREEN}✓${NC} Changes pulled successfully"
|
echo -e "${GREEN}✓${NC} Changes pulled successfully"
|
||||||
log_sync "pull" "from origin/$DOTFILES_BRANCH"
|
log_sync "pull" "from origin/$DOTFILES_BRANCH"
|
||||||
date -Iseconds > "$SYNC_STATE_FILE"
|
date -Iseconds > "$SYNC_STATE_FILE"
|
||||||
|
|
||||||
# Show what changed
|
# Show what changed
|
||||||
echo -e "${CYAN}Updates:${NC}"
|
echo -e "${CYAN}Updates:${NC}"
|
||||||
git log --oneline ORIG_HEAD..HEAD 2>/dev/null | while read -r line; do
|
git log --oneline ORIG_HEAD..HEAD 2>/dev/null | while read -r line; do
|
||||||
@@ -227,14 +226,14 @@ do_pull() {
|
|||||||
done
|
done
|
||||||
else
|
else
|
||||||
echo -e "${RED}✗${NC} Failed to pull changes"
|
echo -e "${RED}✗${NC} Failed to pull changes"
|
||||||
|
|
||||||
# Restore stash on failure
|
# Restore stash on failure
|
||||||
if [[ "$had_changes" == true ]]; then
|
if [[ "$had_changes" == true ]]; then
|
||||||
git stash pop
|
git stash pop
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Restore stash
|
# Restore stash
|
||||||
if [[ "$had_changes" == true ]]; then
|
if [[ "$had_changes" == true ]]; then
|
||||||
echo -e "${BLUE}==>${NC} Restoring local changes..."
|
echo -e "${BLUE}==>${NC} Restoring local changes..."
|
||||||
@@ -249,30 +248,30 @@ do_pull() {
|
|||||||
|
|
||||||
do_sync() {
|
do_sync() {
|
||||||
print_header
|
print_header
|
||||||
|
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
local has_local=$(has_local_changes && echo "yes" || echo "no")
|
local has_local=$(has_local_changes && echo "yes" || echo "no")
|
||||||
local has_remote=$(has_remote_changes && echo "yes" || echo "no")
|
local has_remote=$(has_remote_changes && echo "yes" || echo "no")
|
||||||
|
|
||||||
if [[ "$has_local" == "no" && "$has_remote" == "no" ]]; then
|
if [[ "$has_local" == "no" && "$has_remote" == "no" ]]; then
|
||||||
echo -e "${GREEN}✓${NC} Everything is in sync!"
|
echo -e "${GREEN}✓${NC} Everything is in sync!"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$has_remote" == "yes" ]]; then
|
if [[ "$has_remote" == "yes" ]]; then
|
||||||
echo -e "${CYAN}Remote changes available${NC}"
|
echo -e "${CYAN}Remote changes available${NC}"
|
||||||
do_pull
|
do_pull
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$has_local" == "yes" ]]; then
|
if [[ "$has_local" == "yes" ]]; then
|
||||||
echo -e "${CYAN}Local changes detected${NC}"
|
echo -e "${CYAN}Local changes detected${NC}"
|
||||||
|
|
||||||
# Show changes
|
# Show changes
|
||||||
git status --short
|
git status --short
|
||||||
echo
|
echo
|
||||||
|
|
||||||
read -p "Push these changes? [Y/n]: " confirm
|
read -p "Push these changes? [Y/n]: " confirm
|
||||||
if [[ "${confirm:-y}" =~ ^[Yy] ]]; then
|
if [[ "${confirm:-y}" =~ ^[Yy] ]]; then
|
||||||
read -p "Commit message [Auto-sync from $HOSTNAME]: " msg
|
read -p "Commit message [Auto-sync from $HOSTNAME]: " msg
|
||||||
@@ -285,25 +284,25 @@ do_watch() {
|
|||||||
echo -e "${BLUE}==>${NC} Starting sync daemon..."
|
echo -e "${BLUE}==>${NC} Starting sync daemon..."
|
||||||
echo -e "${DIM}Press Ctrl+C to stop${NC}"
|
echo -e "${DIM}Press Ctrl+C to stop${NC}"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
local interval="${1:-300}" # Default 5 minutes
|
local interval="${1:-300}" # Default 5 minutes
|
||||||
|
|
||||||
log_sync "watch_start" "interval=${interval}s"
|
log_sync "watch_start" "interval=${interval}s"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
local timestamp=$(date '+%H:%M:%S')
|
local timestamp=$(date '+%H:%M:%S')
|
||||||
|
|
||||||
if has_remote_changes; then
|
if has_remote_changes; then
|
||||||
echo -e "[$timestamp] ${YELLOW}↓${NC} Remote changes detected, pulling..."
|
echo -e "[$timestamp] ${YELLOW}↓${NC} Remote changes detected, pulling..."
|
||||||
do_pull
|
do_pull
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if has_local_changes; then
|
if has_local_changes; then
|
||||||
echo -e "[$timestamp] ${YELLOW}↑${NC} Local changes detected"
|
echo -e "[$timestamp] ${YELLOW}↑${NC} Local changes detected"
|
||||||
# In watch mode, auto-commit with timestamp
|
# In watch mode, auto-commit with timestamp
|
||||||
do_push "Auto-sync: $(date '+%Y-%m-%d %H:%M') from $HOSTNAME"
|
do_push "Auto-sync: $(date '+%Y-%m-%d %H:%M') from $HOSTNAME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "[$timestamp] ${DIM}Sleeping ${interval}s...${NC}"
|
echo -e "[$timestamp] ${DIM}Sleeping ${interval}s...${NC}"
|
||||||
sleep "$interval"
|
sleep "$interval"
|
||||||
done
|
done
|
||||||
@@ -312,16 +311,16 @@ do_watch() {
|
|||||||
do_auto() {
|
do_auto() {
|
||||||
# Quick check for shell startup - minimal output
|
# Quick check for shell startup - minimal output
|
||||||
cd "$DOTFILES_DIR" 2>/dev/null || return 0
|
cd "$DOTFILES_DIR" 2>/dev/null || return 0
|
||||||
|
|
||||||
git fetch origin --quiet 2>/dev/null || return 0
|
git fetch origin --quiet 2>/dev/null || return 0
|
||||||
|
|
||||||
local behind=$(git rev-list HEAD..origin/${DOTFILES_BRANCH} --count 2>/dev/null || echo 0)
|
local behind=$(git rev-list HEAD..origin/${DOTFILES_BRANCH} --count 2>/dev/null || echo 0)
|
||||||
|
|
||||||
if [[ $behind -gt 0 ]]; then
|
if [[ $behind -gt 0 ]]; then
|
||||||
echo -e "${YELLOW}⚠ Dotfiles: $behind update(s) available${NC}"
|
echo -e "${YELLOW}⚠ Dotfiles: $behind update(s) available${NC}"
|
||||||
echo -e " Run: ${CYAN}dfpull${NC} or ${CYAN}dotfiles-sync.sh --pull${NC}"
|
echo -e " Run: ${CYAN}dfpull${NC} or ${CYAN}dotfiles-sync.sh --pull${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if has_local_changes; then
|
if has_local_changes; then
|
||||||
local changed=$(git status --short 2>/dev/null | wc -l | tr -d ' ')
|
local changed=$(git status --short 2>/dev/null | wc -l | tr -d ' ')
|
||||||
echo -e "${YELLOW}⚠ Dotfiles: $changed local change(s) not pushed${NC}"
|
echo -e "${YELLOW}⚠ Dotfiles: $changed local change(s) not pushed${NC}"
|
||||||
@@ -331,10 +330,10 @@ do_auto() {
|
|||||||
|
|
||||||
show_diff() {
|
show_diff() {
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
echo -e "${CYAN}Local changes:${NC}"
|
echo -e "${CYAN}Local changes:${NC}"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
if command -v delta &>/dev/null; then
|
if command -v delta &>/dev/null; then
|
||||||
git diff | delta
|
git diff | delta
|
||||||
elif command -v diff-so-fancy &>/dev/null; then
|
elif command -v diff-so-fancy &>/dev/null; then
|
||||||
@@ -346,7 +345,7 @@ show_diff() {
|
|||||||
|
|
||||||
show_log() {
|
show_log() {
|
||||||
local count="${1:-20}"
|
local count="${1:-20}"
|
||||||
|
|
||||||
if [[ -f "$SYNC_LOG_FILE" ]]; then
|
if [[ -f "$SYNC_LOG_FILE" ]]; then
|
||||||
echo -e "${CYAN}Sync history (last $count entries):${NC}"
|
echo -e "${CYAN}Sync history (last $count entries):${NC}"
|
||||||
echo
|
echo
|
||||||
@@ -360,9 +359,9 @@ show_log() {
|
|||||||
|
|
||||||
show_conflicts() {
|
show_conflicts() {
|
||||||
cd "$DOTFILES_DIR"
|
cd "$DOTFILES_DIR"
|
||||||
|
|
||||||
local conflicts=$(git diff --name-only --diff-filter=U 2>/dev/null)
|
local conflicts=$(git diff --name-only --diff-filter=U 2>/dev/null)
|
||||||
|
|
||||||
if [[ -n "$conflicts" ]]; then
|
if [[ -n "$conflicts" ]]; then
|
||||||
echo -e "${RED}Merge conflicts:${NC}"
|
echo -e "${RED}Merge conflicts:${NC}"
|
||||||
echo "$conflicts" | while read -r file; do
|
echo "$conflicts" | while read -r file; do
|
||||||
@@ -415,7 +414,7 @@ main() {
|
|||||||
echo -e "${RED}✗${NC} Dotfiles directory is not a git repository: $DOTFILES_DIR"
|
echo -e "${RED}✗${NC} Dotfiles directory is not a git repository: $DOTFILES_DIR"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
--status|-s)
|
--status|-s)
|
||||||
show_status
|
show_status
|
||||||
|
|||||||
Reference in New Issue
Block a user