Auto-commit submodule changes

This commit is contained in:
KaySar12 2025-05-15 17:40:23 +07:00
parent a915928d08
commit 6ec2257634
4 changed files with 289 additions and 0 deletions

View File

140
scripts/interpreter/gen_commit.py Executable file
View File

@ -0,0 +1,140 @@
import asyncio
import os
import sys
from dotenv import load_dotenv
from interpreter import OpenInterpreter
load_dotenv() # Load environment variables from .env
def get_git_credentials():
"""Retrieve Git credentials and project path from command-line arguments."""
if len(sys.argv) != 4:
print("Usage: python gen_commit.py <GIT_USER> <GIT_PASS> <PROJECT_PATH>")
sys.exit(1)
return sys.argv[1], sys.argv[2], sys.argv[3]
def gen_commit(project_path):
"""Use OpenInterpreter to generate a commit message based on git diff."""
agent = OpenInterpreter()
agent.llm.model = "gpt-4o"
agent.auto_run = True
# Read both convention and git commit files
convention_path = os.path.join(
os.path.dirname(__file__), "resources/commit_convention.md"
)
git_commit_path = os.path.join(os.path.dirname(__file__), "resources/git_commit.md")
with open(convention_path, "r") as f:
convention_content = f.read()
with open(git_commit_path, "r") as f:
git_commit_content = f.read()
agent.system_message = f"""
You are a helpful assistant that generates commit messages based on uncommitted code.
Follow these rules:
1. Use English.
2. Be concise and follow this format:
{convention_content}
3. Use these git commands to analyze changes as you see fit:
{git_commit_content}
4. Only return the commit message. Do not add explanation or extra output.
"""
prompt = f"""
Generate a commit message based on the following changes in the project directory:
First, change directory:
cd {project_path}
Then check the uncommitted changes.
Then generate a commit message according to the changes.
"""
response = agent.chat(prompt)
if isinstance(response, list) and len(response) > 0:
if isinstance(response[-1], dict) and "content" in response[-1]:
return response[-1]["content"].strip()
return str(response).strip()
async def commit_submodules():
"""Commit uncommitted changes in submodules (if any)."""
print("Checking for submodule changes...")
proc = await asyncio.create_subprocess_shell(
"git submodule foreach --quiet '"
"if [ -n \"$(git status --porcelain)\" ]; then "
"echo Committing submodule: $name; "
"git add . && git commit -m \"Auto-commit submodule changes\" || true; "
"fi'",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
if stdout:
print(stdout.decode())
if stderr:
print(f"Submodule commit stderr:\n{stderr.decode()}")
async def push_code():
"""Pull, commit, and push code with AI-generated message."""
git_user, git_pass, project_path = get_git_credentials()
# Change to project path
os.chdir(project_path)
print(f"Changed to project path: {project_path}")
# Get git remote origin URL using asyncio.subprocess
proc = await asyncio.create_subprocess_exec(
"git", "remote", "get-url", "origin",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
git_repo = stdout.decode().strip()
if stderr:
print(f"Failed to get remote URL: {stderr.decode()}")
# Clean URL
git_repo = git_repo.replace(".git", "").replace("https://", "")
remote_url = f"https://{git_user}:{git_pass}@{git_repo}"
# Commit any submodule changes
await commit_submodules()
# Generate commit message
commit_msg = gen_commit(project_path)
print(f"Generated commit message:\n{commit_msg}\n")
# Pull, add, commit, and push
commands = [
f"git pull {remote_url} || true",
"git add .",
f'git commit -m "{commit_msg}" || true',
f"git push {remote_url} || true",
]
for cmd in commands:
proc = await asyncio.create_subprocess_shell(
cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
if stdout:
print(stdout.decode())
if stderr:
print(f"Error executing {cmd}:\n{stderr.decode()}")
if __name__ == "__main__":
asyncio.run(push_code())

View File

@ -0,0 +1,127 @@
# Conventional Commit Messages
See how [a minor change](#examples) to your commit message style can make a difference.
> [!TIP]
> Take a look at **[git-conventional-commits](https://github.com/qoomon/git-conventional-commits)** , a CLI util to ensure these conventions, determine version and generate changelogs
## Commit Message Formats
### Default
<pre>
<b><a href="#types">&lt;type&gt;</a></b></font>(<b><a href="#scopes">&lt;optional scope&gt;</a></b>): <b><a href="#description">&lt;description&gt;</a></b>
<sub>empty separator line</sub>
<b><a href="#body">&lt;optional body&gt;</a></b>
<sub>empty separator line</sub>
<b><a href="#footer">&lt;optional footer&gt;</a></b>
</pre>
### Merge Commit
<pre>
Merge branch '<b>&lt;branch name&gt;</b>'
</pre>
<sup>Follows default git merge message</sup>
### Revert Commit
<pre>
Revert "<b>&lt;reverted commit subject line&gt;</b>"
</pre>
<sup>Follows default git revert message</sup>
### Inital Commit
```
chore: init
```
### Types
- API or UI relevant changes
- `feat` Commits, that add or remove a new feature to the API or UI
- `fix` Commits, that fix an API or UI bug of a preceded `feat` commit
- `refactor` Commits, that rewrite/restructure your code, however do not change any API or UI behaviour
- `perf` Commits are special `refactor` commits, that improve performance
- `style` Commits, that do not affect the meaning (white-space, formatting, missing semi-colons, etc)
- `test` Commits, that add missing tests or correcting existing tests
- `docs` Commits, that affect documentation only
- `build` Commits, that affect build components like build tools, dependencies, project version, ci pipelines, ...
- `ops` Commits, that affect operational components like infrastructure, deployment, backup, recovery, ...
- `chore` Miscellaneous commits e.g. modifying `.gitignore`
### Scopes
The `scope` provides additional contextual information.
* Is an **optional** part of the format
* Allowed Scopes depend on the specific project
* Don't use issue identifiers as scopes
### Breaking Changes Indicator
Breaking changes should be indicated by an `!` before the `:` in the subject line e.g. `feat(api)!: remove status endpoint`
- Is an **optional** part of the format
- Breaking changes **must** be described in the [commit footer section](#footer)
### Description
The `description` contains a concise description of the change.
- It is a **mandatory** part of the format
- Use the imperative, present tense: "change" not "changed" nor "changes"
- Think of `This commit will...` or `This commit should...`
- Don't capitalize the first letter
- No dot (`.`) at the end
### Body
The `body` should include the motivation for the change and contrast this with previous behavior.
- Is an **optional** part of the format
- Use the imperative, present tense: "change" not "changed" nor "changes"
- This is the place to mention issue identifiers and their relations
### Footer
The `footer` should contain any information about **Breaking Changes** and is also the place to **reference Issues** that this commit refers to.
- Is an **optional** part of the format
- **optionally** reference an issue by its id.
- **Breaking Changes** should start with the word `BREAKING CHANGE:` followed by space or two newlines. The rest of the commit message is then used for this.
### Versioning
- **If** your next release contains commit with...
- **breaking changes** incremented the **major version**
- **API relevant changes** (`feat` or `fix`) incremented the **minor version**
- **Else** increment the **patch version**
### Examples
- ```
feat: add email notifications on new direct messages
```
- ```
feat(shopping cart): add the amazing button
```
- ```
feat!: remove ticket list endpoint
refers to JIRA-1337
BREAKING CHANGE: ticket endpoints no longer supports list all entities.
```
- ```
fix(shopping-cart): prevent order an empty shopping cart
```
- ```
fix(api): fix wrong calculation of request body checksum
```
- ```
fix: add missing parameter to service call
The error occurred due to <reasons>.
```
- ```
perf: decrease memory footprint for determine uniqe visitors by using HyperLogLog
```
- ```
build: update dependencies
```
- ```
build(release): bump version to 1.0.0
```
- ```
refactor: implement fibonacci number calculation as recursion
```
- ```
style: remove empty line
```

View File

@ -0,0 +1,22 @@
How to show uncommitted changes in Git
The command you are looking for is git diff.
git diff - Show changes between commits, commit and working tree, etc
Here are some of the options it expose which you can use
git diff (no parameters)
Print out differences between your working directory and the index.
git diff --cached:
Print out differences between the index and HEAD (current commit).
git diff HEAD:
Print out differences between your working directory and the HEAD.
git diff --name-only
Show only names of changed files.
git diff --name-status
Show only names and status of changed files.