Skip to content

Commit

Permalink
feat: commit only staged files
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinzent03 committed Aug 16, 2022
1 parent ad9d0f8 commit f6f4a97
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 18 deletions.
25 changes: 16 additions & 9 deletions src/isomorphicGit.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import git, { AuthCallback, Errors, GitHttpRequest, GitHttpResponse, GitProgressEvent, HttpClient } from "isomorphic-git";
import git, { AuthCallback, Errors, GitHttpRequest, GitHttpResponse, GitProgressEvent, HttpClient, Walker } from "isomorphic-git";
import { Notice, requestUrl } from 'obsidian';
import { GitManager } from "./gitManager";
import ObsidianGit from './main';
import { MyAdapter } from './myAdapter';
import { BranchInfo, FileStatusResult, PluginState, Status } from "./types";
import { BranchInfo, FileStatusResult, PluginState, Status, WalkDifference } from "./types";


export class IsomorphicGit extends GitManager {
Expand Down Expand Up @@ -494,13 +494,15 @@ export class IsomorphicGit extends GitManager {
return;
}

async getFileChangesCount(commitHash1: string, commitHash2: string): Promise<{
path: string,
type: "modify" | "add" | "remove",
}[]> {
const res = await git.walk({
async getFileChangesCount(commitHash1: string, commitHash2: string): Promise<WalkDifference[]> {
return this.walkDifference([git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })]);
}


async walkDifference(walker: Walker[]): Promise<WalkDifference[]> {
const res = await this.wrapFS(git.walk({
...this.getRepo(),
trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })],
trees: walker,
map: async function (filepath, [A, B]) {
// ignore directories
if (filepath === '.') {
Expand Down Expand Up @@ -539,10 +541,15 @@ export class IsomorphicGit extends GitManager {
type: type,
};
},
});
}));
return res;
}

async getStagedFiles(): Promise<{ vault_path: string; }[]> {
const res = await this.walkDifference([git.TREE({ ref: "HEAD" }), git.STAGE()]);
return res.map((file) => { return { vault_path: this.getVaultPath(file.path) }; });
}

async getDiffString(filePath: string): Promise<string> {
throw new Error("Method not implemented.");
};
Expand Down
44 changes: 35 additions & 9 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ export default class ObsidianGit extends Plugin {
callback: () => this.promiseQueue.addTask(() => this.commit(false, true))
});

this.addCommand({
id: "commit-staged",
name: "Commit staged",
callback: () => this.promiseQueue.addTask(() => this.commit(false, false, true))
});

this.addCommand({
id: "commit-staged-specified-message",
name: "Commit staged with specific message",
callback: () => this.promiseQueue.addTask(() => this.commit(false, true, true))
});

this.addCommand({
id: "push2",
name: "Push",
Expand Down Expand Up @@ -527,12 +539,13 @@ export default class ObsidianGit extends Plugin {
this.setState(PluginState.idle);
}

async commit(fromAutoBackup: boolean, requestCustomMessage: boolean = false): Promise<boolean> {
async commit(fromAutoBackup: boolean, requestCustomMessage: boolean = false, onlyStaged: boolean = false): Promise<boolean> {
if (!await this.isAllInitialized()) return false;

const hadConflict = localStorage.getItem(this.manifest.id + ":conflict") === "true";

let status;
let changedFiles: { vault_path: string; }[];
let status: Status | undefined;

if (this.gitManager instanceof SimpleGit) {
const file = this.app.vault.getAbstractFileByPath(this.conflictOutputFile);
Expand All @@ -545,6 +558,7 @@ export default class ObsidianGit extends Plugin {
this.handleConflict(status.conflicted);
return;
}
changedFiles = [...status.changed, ...status.staged];
} else if (fromAutoBackup && hadConflict) {
this.setState(PluginState.conflicted);
this.displayError(`Did not commit, because you have conflict files. Please resolve them and commit per command.`);
Expand All @@ -553,19 +567,24 @@ export default class ObsidianGit extends Plugin {
const file = this.app.vault.getAbstractFileByPath(this.conflictOutputFile);
await this.app.vault.delete(file);
status = await this.updateCachedStatus();
changedFiles = [...status.changed, ...status.staged];
} else {
status = await this.updateCachedStatus();
if (onlyStaged) {
changedFiles = await (this.gitManager as IsomorphicGit).getStagedFiles();
} else {
status = await this.updateCachedStatus();
changedFiles = [...status.changed, ...status.staged];
}
}


if (await this.hasTooBigFiles([...status.staged, ...status.changed])) {
if (await this.hasTooBigFiles(changedFiles)) {
this.setState(PluginState.idle);
return false;
}

const changedFiles = status.changed.length + status.staged.length;

if (changedFiles !== 0 || hadConflict) {
if (changedFiles.length !== 0 || hadConflict) {
let commitMessage = fromAutoBackup ? this.settings.autoCommitMessage : this.settings.commitMessage;
if ((fromAutoBackup && this.settings.customMessageOnAutoBackup) || requestCustomMessage) {
if (!this.settings.disablePopups && fromAutoBackup) {
Expand All @@ -580,10 +599,17 @@ export default class ObsidianGit extends Plugin {
return false;
}
}
let committedFiles = await this.gitManager.commitAll(commitMessage, status);
let committedFiles: number | undefined;
if (onlyStaged) {
committedFiles = await this.gitManager.commit(commitMessage);
} else {
committedFiles = await this.gitManager.commitAll(commitMessage, status);

}
let roughly = false;
if (committedFiles === undefined) {
committedFiles = status.changed.length + status.staged.length;
roughly = true;
committedFiles = changedFiles.length;
}
this.displayMessage(`Committed${roughly ? " approx." : ""} ${committedFiles} ${committedFiles > 1 ? 'files' : 'file'}`);
} else {
Expand All @@ -595,7 +621,7 @@ export default class ObsidianGit extends Plugin {
return true;
}

async hasTooBigFiles(files: FileStatusResult[]): Promise<boolean> {
async hasTooBigFiles(files: ({ vault_path: string; })[]): Promise<boolean> {
const branchInfo = await this.gitManager.branchInfo();
const remote = branchInfo.tracking?.split("/")[0];

Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ export enum PluginState {
conflicted,
}

export interface WalkDifference {
path: string;
type: | "modify" | "add" | "remove";
}

export interface BranchInfo {
current: string;
tracking: string;
Expand Down

0 comments on commit f6f4a97

Please sign in to comment.