mirror of
https://github.com/silvanocerza/github-gitless-sync.git
synced 2026-07-22 05:41:36 +00:00
Handle first sync with completely empty repository
This commit is contained in:
parent
cd98f0a392
commit
923a811a4a
2 changed files with 62 additions and 3 deletions
|
|
@ -131,4 +131,24 @@ export default class GithubClient {
|
||||||
});
|
});
|
||||||
return res.json;
|
return res.json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new file in the repo, the content must be base64 encoded or the request will fail.
|
||||||
|
*
|
||||||
|
* @param message commit message
|
||||||
|
* @param path path to create in the repo
|
||||||
|
* @param content base64 encoded content of the file
|
||||||
|
*/
|
||||||
|
async createFile(path: string, content: string, message: string) {
|
||||||
|
await requestUrl({
|
||||||
|
url: `https://api.github.com/repos/${this.owner}/${this.repo}/contents/${path}`,
|
||||||
|
headers: this.headers(),
|
||||||
|
method: "PUT",
|
||||||
|
body: JSON.stringify({
|
||||||
|
message: message,
|
||||||
|
content: content,
|
||||||
|
branch: this.branch,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { Vault, normalizePath } from "obsidian";
|
||||||
import GithubClient, {
|
import GithubClient, {
|
||||||
GetTreeResponseItem,
|
GetTreeResponseItem,
|
||||||
NewTreeRequestItem,
|
NewTreeRequestItem,
|
||||||
|
RepoContent,
|
||||||
} from "./github/client";
|
} from "./github/client";
|
||||||
import MetadataStore, { FileMetadata, Metadata } from "./metadata-store";
|
import MetadataStore, { FileMetadata, Metadata } from "./metadata-store";
|
||||||
import EventsListener from "./events-listener";
|
import EventsListener from "./events-listener";
|
||||||
|
|
@ -85,7 +86,41 @@ export default class SyncManager {
|
||||||
* This fails neither remote nor local folders are empty.
|
* This fails neither remote nor local folders are empty.
|
||||||
*/
|
*/
|
||||||
async firstSync() {
|
async firstSync() {
|
||||||
const { files, sha: treeSha } = await this.client.getRepoContent();
|
let repositoryIsBare = false;
|
||||||
|
let res: RepoContent;
|
||||||
|
let files: {
|
||||||
|
[key: string]: GetTreeResponseItem;
|
||||||
|
} = {};
|
||||||
|
let treeSha: string = "";
|
||||||
|
try {
|
||||||
|
res = await this.client.getRepoContent();
|
||||||
|
files = res.files;
|
||||||
|
treeSha = res.sha;
|
||||||
|
} catch (err) {
|
||||||
|
if (err.status !== 409) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// The repository is bare, meaning it has no tree, no commits and no branches
|
||||||
|
repositoryIsBare = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (repositoryIsBare) {
|
||||||
|
// Since the repository is completely empty we need to create a first commit.
|
||||||
|
// We can't create that by going throught the normal sync process since the
|
||||||
|
// API doesn't let us create a new tree when the repo is empty.
|
||||||
|
// So we create a the manifest file as the first commit, since we're going
|
||||||
|
// to create that in any case right after this.
|
||||||
|
await this.client.createFile(
|
||||||
|
`${this.vault.configDir}/github-sync-metadata.json`,
|
||||||
|
"",
|
||||||
|
"Initial commit",
|
||||||
|
);
|
||||||
|
// Now get the repo content again cause we know for sure it will return a
|
||||||
|
// valid sha that we can use to create the first sync commit.
|
||||||
|
res = await this.client.getRepoContent();
|
||||||
|
files = res.files;
|
||||||
|
treeSha = res.sha;
|
||||||
|
}
|
||||||
|
|
||||||
const remoteContentDirIsEmpty = this.remoteContentDirIsEmpty(files);
|
const remoteContentDirIsEmpty = this.remoteContentDirIsEmpty(files);
|
||||||
const localContentDirIsEmpty = await this.localContentDirIsEmpty();
|
const localContentDirIsEmpty = await this.localContentDirIsEmpty();
|
||||||
|
|
@ -93,7 +128,7 @@ export default class SyncManager {
|
||||||
if (!remoteContentDirIsEmpty && !localContentDirIsEmpty) {
|
if (!remoteContentDirIsEmpty && !localContentDirIsEmpty) {
|
||||||
// Both have files, we can't sync, show error
|
// Both have files, we can't sync, show error
|
||||||
throw new Error("Both remote and local have files, can't sync");
|
throw new Error("Both remote and local have files, can't sync");
|
||||||
} else if (remoteContentDirIsEmpty) {
|
} else if (remoteContentDirIsEmpty || repositoryIsBare) {
|
||||||
// Remote has no files and no manifest, let's just upload whatever we have locally.
|
// Remote has no files and no manifest, let's just upload whatever we have locally.
|
||||||
// This is fine even if the local content dir is empty.
|
// This is fine even if the local content dir is empty.
|
||||||
// The most important thing at this point is that the remote manifest is created.
|
// The most important thing at this point is that the remote manifest is created.
|
||||||
|
|
@ -624,7 +659,11 @@ export default class SyncManager {
|
||||||
let remotePath = filePath;
|
let remotePath = filePath;
|
||||||
if (!filePath.startsWith(this.vault.configDir)) {
|
if (!filePath.startsWith(this.vault.configDir)) {
|
||||||
if (this.settings.localContentDir === "") {
|
if (this.settings.localContentDir === "") {
|
||||||
remotePath = `${this.settings.repoContentDir}/${filePath}`;
|
if (this.settings.repoContentDir === "") {
|
||||||
|
remotePath = filePath;
|
||||||
|
} else {
|
||||||
|
remotePath = `${this.settings.repoContentDir}/${filePath}`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
remotePath = filePath.replace(
|
remotePath = filePath.replace(
|
||||||
this.settings.localContentDir,
|
this.settings.localContentDir,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue