Skip to content

feat(dotfiles-updater): skip build/switch when no changes detected - #558

Merged
shunkakinoki merged 3 commits into
mainfrom
feat/skip-dotfiles-update-if-no-changes
Jan 12, 2026
Merged

feat(dotfiles-updater): skip build/switch when no changes detected#558
shunkakinoki merged 3 commits into
mainfrom
feat/skip-dotfiles-update-if-no-changes

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Jan 12, 2026

Copy link
Copy Markdown
Owner

Summary

Skip the `make build && make switch` step when the periodic 3hr dotfiles-updater runs and there are no new changes in git.

Changes

  • Store the current commit hash before fetching
  • Compare with `origin/main` after fetch
  • Only run `install.sh` if commits differ
  • Log which commits changed for debugging

Why

Saves CPU/time when there are no dotfiles changes to apply. The 3hr update cycle will now be a quick no-op check instead of a full rebuild.


Summary by cubic

Dotfiles updater now fetches origin/main, compares HEAD to it, and exits early if identical—skipping install.sh (make build && make switch). This makes the 3‑hour update a fast no‑op when there are no changes and saves CPU.

Written for commit b4dd1d8. Summary will update on new commits.

Copilot AI review requested due to automatic review settings January 12, 2026 12:10
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces an efficiency improvement to the periodic dotfiles-updater service. By implementing a check for new Git commits, the script avoids unnecessary rebuilds and system switches when the dotfiles repository has not changed. This optimization transforms routine update cycles into quick, resource-light checks, enhancing overall system performance and responsiveness.

Highlights

  • Performance Optimization: The dotfiles-updater script now includes logic to detect if there are any new changes in the Git repository before proceeding with the make build && make switch steps. This significantly reduces CPU usage and execution time when no updates are available.
  • Conditional Execution: The core build and switch operations are now conditionally executed. If the local repository's HEAD commit matches origin/main after fetching, the script will exit early, effectively becoming a no-op.
  • Git Commit Comparison: The script stores the current commit hash, fetches the latest changes from origin/main, and then compares the local HEAD with the remote HEAD to determine if an update is necessary.
  • Improved Logging: Added informative log messages indicating whether changes were detected or if the build/switch process was skipped, including truncated commit hashes for clarity.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Only run install.sh (make build && make switch) when there are actual
git changes from origin/main. This avoids unnecessary rebuilds during
the periodic 3hr update cycle.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR adds a sensible optimization to the dotfiles updater, skipping the build and switch when there are no new commits. The implementation is correct and will save resources. One point of feedback for future improvement: the install.sh script, which is subsequently called, performs redundant git fetch and pull operations. Since this update.sh script now ensures the repository is up-to-date, these operations in install.sh could be skipped, for instance by checking the AUTOMATED_UPDATE environment variable. This is out of scope for this PR but would be a good follow-up to improve efficiency.

REMOTE_COMMIT=$(git rev-parse origin/main)

# Check if there are any changes
if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better robustness and to follow modern bash best practices, it's recommended to use the [[ ... ]] compound command for tests instead of the POSIX [ ... ]. The [[ keyword is specific to bash (and other modern shells) and is safer as it prevents issues like word splitting on variable expansions. While your use of quotes makes the current code safe, [[ is generally preferred for new bash code. When using [[, it's also idiomatic to use == for string comparison.

Suggested change
if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then
if [[ "$CURRENT_COMMIT" == "$REMOTE_COMMIT" ]]; then

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Dotfiles updater now detects whether remote changes exist before applying updates
    • Skips unnecessary updates when already synchronized with the latest version
    • Logs concise change summary when an update is applied
  • Tests

    • Added tests covering change detection, skip behavior when up-to-date, and update logging

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds a pre-fetch commit comparison to the dotfiles-updater script: it records the current local commit, fetches origin/main, compares remote vs local, exits early if identical, or logs the change range and hard-resets to origin/main when different. Tests for change-detection were added.

Changes

Cohort / File(s) Summary
Script enhancement
home-manager/services/dotfiles-updater/update.sh
Save current commit hash, fetch origin/main, retrieve remote commit hash, compare hashes, early-exit when identical, log short hash range and perform git reset --hard when different
Test coverage
spec/dotfiles_updater_spec.sh
New "change detection" tests: verify storing current commit, retrieving remote commit after fetch, detecting no-change to skip build, and logging when changes are detected; installation assertion retained

Sequence Diagram(s)

(omitted — changes are localized to a single script and test suite; not generating diagrams)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I saved a hop by checking the trail,
Local and origin, I sniffed every tail,
If they're the same, I nap with delight,
If not, I hop forward and set things right,
✨🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing early-exit optimization to skip build/switch when no dotfiles changes are detected.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation (CPU/time savings), implementation approach (commit comparison), and expected behavior of the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/skip-dotfiles-update-if-no-changes

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7306027 and b4dd1d8.

📒 Files selected for processing (1)
  • spec/dotfiles_updater_spec.sh
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{sh,bash}

📄 CodeRabbit inference engine (CLAUDE.md)

Use shfmt with 2-space indentation for shell scripts

**/*.{sh,bash}: Use 2 spaces for indentation in shell scripts
Add proper shebang lines to shell scripts
Follow shellcheck recommendations in shell scripts
Document complex commands in shell scripts
Use consistent variable naming in shell scripts

Files:

  • spec/dotfiles_updater_spec.sh
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: docker-build-push (linux/arm64, arm64, ubuntu-24.04-arm)
  • GitHub Check: docker-build-push (linux/amd64, amd64, ubuntu-latest)
  • GitHub Check: nix-nixos
  • GitHub Check: nix-linux
  • GitHub Check: nix-darwin
  • GitHub Check: e2e-run (MacOS, macos-latest)
  • GitHub Check: e2e-run (Ubuntu, ubuntu-latest)
  • GitHub Check: e2e-run (NixOS, ubuntu-latest)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Mesa Description
  • GitHub Check: shell-test
  • GitHub Check: lua-hammerspoon
  • GitHub Check: lua-neovim-test
  • GitHub Check: lua-neovim
  • GitHub Check: shell-lint
🔇 Additional comments (2)
spec/dotfiles_updater_spec.sh (2)

53-81: New change detection tests look good overall.

The test suite properly covers the new change-detection flow: storing pre-fetch commit, retrieving post-fetch remote commit, comparison logic, and logging for both change/no-change scenarios. The shellcheck disable=SC2016 directives are correctly placed for lines containing $() in single-quoted strings.

One minor observation: the comparison test on line 67 uses a loose pattern 'CURRENT_COMMIT.*=.*REMOTE_COMMIT'. If the script uses [[ "$CURRENT_COMMIT" == "$REMOTE_COMMIT" ]] or similar, you might consider a more precise pattern to avoid false positives. However, this is acceptable for basic coverage.


1-89: Test file structure and conventions are sound.

The file follows coding guidelines with 2-space indentation, proper shebang, and appropriate shellcheck disable directives. The grep-based testing pattern is consistent throughout and provides reasonable coverage of the new change-detection feature.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Add ShellSpec tests to verify:
- Current commit is stored before fetch
- Remote commit is retrieved after fetch
- Commits are compared to detect changes
- Appropriate messages are logged for both cases

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the periodic dotfiles-updater service by adding a check to skip the expensive build and switch operations when no changes are detected in the remote repository.

Changes:

  • Add commit hash comparison before and after fetching to detect changes
  • Skip the install.sh execution when current commit matches remote commit
  • Add detailed logging to show which commits changed for debugging

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +26
if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then
echo "No changes detected (current: ${CURRENT_COMMIT:0:8}). Skipping build and switch."
exit 0
fi

Copilot AI Jan 12, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new commit comparison logic lacks test coverage. Consider adding tests to verify:

  1. The script exits early when CURRENT_COMMIT equals REMOTE_COMMIT
  2. The script proceeds with installation when commits differ
  3. The appropriate log messages are output in each case

This is important functionality that should be tested given the repository has comprehensive test coverage for shell scripts.

Copilot uses AI. Check for mistakes.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="home-manager/services/dotfiles-updater/update.sh">

<violation number="1" location="home-manager/services/dotfiles-updater/update.sh:25">
P2: Early exit skips `git reset --hard`, leaving dirty working tree unchanged when no upstream changes.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

# Check if there are any changes
if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then
echo "No changes detected (current: ${CURRENT_COMMIT:0:8}). Skipping build and switch."
exit 0

@cubic-dev-ai cubic-dev-ai Bot Jan 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Early exit skips git reset --hard, leaving dirty working tree unchanged when no upstream changes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/services/dotfiles-updater/update.sh, line 25:

<comment>Early exit skips `git reset --hard`, leaving dirty working tree unchanged when no upstream changes.</comment>

<file context>
@@ -10,8 +10,24 @@ if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then
+# Check if there are any changes
+if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then
+  echo "No changes detected (current: ${CURRENT_COMMIT:0:8}). Skipping build and switch."
+  exit 0
+fi
+
</file context>
Suggested change
exit 0
git reset --hard origin/main
exit 0
Fix with Cubic

@shunkakinoki
shunkakinoki enabled auto-merge (squash) January 12, 2026 12:19
ShellCheck complains about unexpanded expressions in single quotes,
but these are intentional literal string matches in test assertions.

@mesa-dot-dev mesa-dot-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performed full review of 2535acb...e42dc40

Analysis

  1. No state tracking for failed installs - only checks if git commits match, not whether the last install.sh run was successful. Failed installs won't retry until new commits arrive.

  2. Limited error handling strategy - script lacks explicit error handling for git operations. Network failures during git fetch will cause hard exit without clear debugging information.

  3. Silent discarding of local changes - git reset --hard operation will remove any local modifications without warning, potentially causing unexpected behavior for users testing changes.

Tip

Help

Slash Commands:

  • /review - Request a full code review
  • /review latest - Review only changes since the last review
  • /describe - Generate PR description. This will update the PR body or issue comment depending on your configuration
  • /help - Get help with Mesa commands and configuration options

0 files reviewed | 2 comments | Edit Agent SettingsRead Docs

REMOTE_COMMIT=$(git rev-parse origin/main)

# Check if there are any changes
if [ "$CURRENT_COMMIT" = "$REMOTE_COMMIT" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

This optimization skips the install when commits match, but doesn't account for scenarios where the previous install.sh run may have failed partially. Consider tracking the last successful install commit in a state file (e.g., ~/.dotfiles-updater-last-success) and comparing against that instead of just HEAD. This would ensure a retry if the previous install failed.

Agent: 🏛 Architecture • Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#558
File: home-manager/services/dotfiles-updater/update.sh#L23
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
This optimization skips the install when commits match, but doesn't account for scenarios where the previous install.sh run may have failed partially. Consider tracking the last successful install commit in a state file (e.g., ~/.dotfiles-updater-last-success) and comparing against that instead of just HEAD. This would ensure a retry if the previous install failed.

CURRENT_COMMIT=$(git rev-parse HEAD)

# Fetch latest changes
git fetch origin main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

Consider adding error handling for the git fetch operation. If the fetch fails (network issues, remote unavailable), the script will exit due to set -e, but REMOTE_COMMIT will never be set. Adding explicit error handling or at least logging would make debugging easier:

if ! git fetch origin main; then
  echo "Failed to fetch from origin/main"
  exit 1
fi

Agent: 🏛 Architecture • Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#558
File: home-manager/services/dotfiles-updater/update.sh#L17
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Consider adding error handling for the git fetch operation. If the fetch fails (network issues, remote unavailable), the script will exit due to `set -e`, but REMOTE_COMMIT will never be set. Adding explicit error handling or at least logging would make debugging easier:
```bash
if ! git fetch origin main; then
  echo "Failed to fetch from origin/main"
  exit 1
fi

</details>

@mesa-dot-dev

mesa-dot-dev Bot commented Jan 12, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Dotfiles updater now fetches origin/main, compares HEAD to it, and exits early if identical—skipping install.sh (make build && make switch). This makes the 3‑hour update a fast no‑op when there are no changes and saves CPU.

What changed?

  • Store the current commit hash before fetching
  • Compare with origin/main after fetch
  • Only run install.sh if commits differ
  • Log which commits changed for debugging

Why

Saves CPU/time when there are no dotfiles changes to apply. The 3hr update cycle will now be a quick no-op check instead of a full rebuild.


Summary by cubic

Dotfiles updater now fetches origin/main, compares HEAD to it, and exits early if identical—skipping install.sh (make build && make switch). This makes the 3‑hour update a fast no‑op when there are no changes and saves CPU.

Written for commit e42dc40. Summary will update on new commits.

Description generated by Mesa. Update settings

@mesa-dot-dev

mesa-dot-dev Bot commented Jan 12, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Dotfiles updater now fetches origin/main, compares HEAD to it, and exits early if identical—skipping install.sh (make build && make switch). This makes the 3‑hour update a fast no‑op when there are no changes and saves CPU.

What changed?

  • Store the current commit hash before fetching
  • Compare with origin/main after fetch
  • Only run install.sh if commits differ
  • Log which commits changed for debugging

Description generated by Mesa. Update settings

@mesa-dot-dev

mesa-dot-dev Bot commented Jan 12, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Skip the make build && make switch step when the periodic 3hr dotfiles-updater runs and there are no new changes in git.

What changed?

  • Store the current commit hash before fetching
  • Compare with origin/main after fetch
  • Only run install.sh if commits differ
  • Log which commits changed for debugging

Description generated by Mesa. Update settings

@shunkakinoki
shunkakinoki merged commit 9a9c518 into main Jan 12, 2026
30 checks passed
@shunkakinoki
shunkakinoki deleted the feat/skip-dotfiles-update-if-no-changes branch January 12, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants