Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete and rename branch #31

Merged
merged 7 commits into from
Nov 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/app/features/repositories/repositories.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
Current Branch
</div>
<div class="title">
<span class="text-nowrap">
{{activeBranch?.name}}
</span>
<span class="text-nowrap">
{{activeBranch?.name}}
</span>
<div class="status">
<div *ngIf="statusSummary?.behind > 0"
class="badge badge-pill badge-secondary bg-info pull-request">
Expand Down
26 changes: 15 additions & 11 deletions src/app/features/repositories/repositories.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { interval, of, Subject } from 'rxjs';
import { RepositoriesMenuService } from '../../shared/state/UI/repositories-menu';
import { debounceTime, distinctUntilChanged, switchMap, takeUntil, takeWhile } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged, switchMap, takeUntil, takeWhile, tap } from 'rxjs/operators';
import { RepositoriesService, Repository } from '../../shared/state/DATA/repositories';
import { fromPromise } from 'rxjs/internal-compatibility';
import { StatusSummary } from '../../shared/model/statusSummary.model';
import { FileWatchesService } from '../../shared/state/system/File-Watches';
import { RepositoryBranchesService, RepositoryBranchSummary } from '../../shared/state/DATA/repository-branches';
Expand Down Expand Up @@ -94,7 +93,7 @@ export class RepositoriesComponent implements OnInit, OnDestroy {
takeUntil(this.componentDestroyed),
takeWhile(() => this.isViewChangeTo === 'changes'),
switchMap(() => {
console.log('running')
console.log('running');
if (!!this.repository && !!this.activeBranch) {
return this.repositoriesService.fetch(
{ ...this.repository } as Repository,
Expand Down Expand Up @@ -139,8 +138,9 @@ export class RepositoriesComponent implements OnInit, OnDestroy {
// }
return of(null);
}),
switchMap(() => fromPromise(this.repositoryBranchesService.load(this.repository))),
switchMap(() => this.observingBranchStatus())
tap(() => this.repositoryBranchesService.load(this.repository)),
switchMap(() => this.observingBranchStatus()),
distinctUntilChanged(),
)
.subscribe(
(status: StatusSummary) => {
Expand All @@ -156,13 +156,17 @@ export class RepositoriesComponent implements OnInit, OnDestroy {
* Observing branch status
*/
private watchingBranch() {
this.repositoryBranchesService.select()
.subscribe(
listBranch => {
this.repositoryBranchesService
.select()
.pipe(
switchMap(listBranch => {
this.branches = listBranch;
this.activeBranch = listBranch.find(branch => {
return branch.current;
});
return this.repositoryBranchesService.selectActive();
})
)
.subscribe(
activeBranch => {
this.activeBranch = activeBranch;
}
);
}
Expand Down
240 changes: 125 additions & 115 deletions src/app/services/features/git.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,104 +78,87 @@ export class GitService {
* @param oldBranches Retrieve from repository configs
*/
async getBranchInfo(directory: string, oldBranches: RepositoryBranchSummary[] = []): Promise<RepositoryBranchSummary[]> {
const branchRemoteRaw = await this.gitInstance(directory).branch(['-r']);
const branchLocalRaw = await this.gitInstance(directory).branch([]);
const branchRemoteRaw = await this.branch(directory, '-r', '-vv');
const branchLocalRaw = await this.branch(directory, '-vv');
const branchTracking = await this.getBranchTracking(directory);

if (!branchTracking) {
return null;
return [];
}

const branchesOutPut: RepositoryBranchSummary[] = [];

if (branchRemoteRaw.all.length > branchLocalRaw.all.length) {
// In case there is no local-only branch.
Object.keys(branchRemoteRaw.branches).forEach(branchRemoteInstance => {
const slidedSlash = branchRemoteInstance.split('/');
const trackingOn = branchTracking.find(track => track.name === slidedSlash[0]);
const extractedNameRemote = slidedSlash.slice(1).join('/'); // remove origin/
const existInstanceLocal = branchLocalRaw.all.find(nameLocalBranch => nameLocalBranch === extractedNameRemote);
if (!!existInstanceLocal && existInstanceLocal.length > 0) {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[branchRemoteInstance],
existInstanceLocal,
branchLocalRaw.branches[existInstanceLocal].current,
null, trackingOn, true, true
);
branchesOutPut.push(branchItem);
} else {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[branchRemoteInstance],
branchRemoteInstance,
branchRemoteRaw.branches[branchRemoteInstance].current,
null, trackingOn, true, false
);
branchesOutPut.push(branchItem);
}
});
} else {
// In case there are local-only branch.
Object.keys(branchLocalRaw.branches).forEach(branchLocalInstance => {
let trackingOn = null;
const existRemoteLocal = branchRemoteRaw.all.find(nameRemoteBranch => {
const slidedSlash = nameRemoteBranch.split('/');
trackingOn = branchTracking.find(track => track.name === slidedSlash[0]);
const extractedNameRemote = slidedSlash.slice(1).join('/'); // remove origin/
return branchLocalInstance === extractedNameRemote;
});
if (!!existRemoteLocal && existRemoteLocal.length > 0) {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[existRemoteLocal],
branchLocalInstance,
branchLocalRaw.branches[branchLocalInstance].current,
null, trackingOn, true, true
);
branchesOutPut.push(branchItem);
} else {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[existRemoteLocal],
branchLocalInstance,
branchLocalRaw.branches[branchLocalInstance].current,
null, trackingOn, false, true
);
branchesOutPut.push(branchItem);
}
});
}

// update from oldBranch
if (branchesOutPut.length > oldBranches.length) {
branchesOutPut.forEach((branch, index, selfArr) => {
const findFromOld = this.findBranchFromListBranch(branch, oldBranches);
// result from remote first
// after that, looping all local and check for local-only branch and status.
Object.keys(branchRemoteRaw.branches).forEach(branchRemoteName => {
// contain [<name tracker>, <name branch>, etc]
// tracker normally will be origin
const slidedSlash = branchRemoteName.split('/');
const trackingOn = branchTracking.find(track => track.name === slidedSlash[0]);
// get the true name of the branch be hind tracker
const branchName = slidedSlash.slice(1).join('/');
// If exist local, copy the current and change the local/remote status
const existInstanceLocal = branchLocalRaw.all.find(
nameLocalBranch => nameLocalBranch === branchName
);
if (!!existInstanceLocal) {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[branchRemoteName],
branchName,
branchLocalRaw.branches[existInstanceLocal].current,
null, trackingOn, true, true
);
branchesOutPut.push(branchItem);
} else {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchRemoteRaw.branches[branchRemoteName],
branchName,
branchRemoteRaw.branches[branchRemoteName].current,
null, trackingOn, true, false
);
branchesOutPut.push(branchItem);
}
});

if (findFromOld) {
selfArr[index].id = findFromOld.id;
selfArr[index].last_update = findFromOld.last_update;
selfArr[index].options = findFromOld.options;
} else {
selfArr[index].id = this.securityService.randomID;
selfArr[index].last_update = null;
selfArr[index].options = null;
}
});
} else {
oldBranches.forEach((branch, index, selfArr) => {
const findFromNew = this.findBranchFromListBranch(branch, branchesOutPut);
// Looping all local array to find "local only"
Object.keys(branchLocalRaw.branches).forEach(branchLocalName => {
const existedValue = branchesOutPut.find(br => br.name === branchLocalName);
/**
* Branch local only will not in remotes
*/
if (!existedValue) {
const branchItem: RepositoryBranchSummary = GitService.repositoryBranchBuilder(
branchLocalRaw.branches[branchLocalName],
branchLocalName,
branchLocalRaw.branches[branchLocalName].current,
null, null, false, true
);
branchesOutPut.push(branchItem);
}
});

if (findFromNew) {
findFromNew.id = selfArr[index].id;
findFromNew.last_update = selfArr[index].last_update;
findFromNew.options = selfArr[index].options;
} else {
// do nothing, will be removed as both local and remote cannot be found
// This can be due to branch removed, renamed, etc.
}
});
}
// update other information from oldBranch
branchesOutPut.forEach((branch, index, self) => {
const existed = oldBranches.find(ob => ob.name === branch.name);
if (existed) {
branchesOutPut[index].id = existed.id;
branchesOutPut[index].last_update = existed.last_update;
branchesOutPut[index].options = existed.options;
} else {
branchesOutPut[index].id = this.securityService.randomID;
branchesOutPut[index].last_update = null;
branchesOutPut[index].options = null;
}
});

console.log(branchesOutPut);
return branchesOutPut;
}

branch(directory: string, ...options: string[]) {
return this.gitInstance(directory)
.branch(options);
}

async cloneTo(cloneURL: string, directory: string, credentials?: Account) {
let urlRemote = cloneURL;
directory = directory + this.utilities.repositoryNameFromHTTPS(cloneURL);
Expand Down Expand Up @@ -232,6 +215,12 @@ export class GitService {
}

async fetchInfo(repository: Repository, credentials: Account, branch: RepositoryBranchSummary) {
if (!branch.tracking) {
return {
fetchData: null,
repository
};
}
// retrieve the directory for gitInstance to execute
const { directory } = repository;
let urlRemote = branch.tracking.fetch;
Expand Down Expand Up @@ -276,25 +265,39 @@ export class GitService {

/**
* TODO: checking git issue for more info.
* @param repository
* @param branchURL
* @param credentials
* @param directory
* @param branchName
* @param remoteType
* @param options
*/
push(repository: Repository, branchURL: string, credentials: Account, options?: { [o: string]: string }) {
const urlRemote = this.utilities.addCredentialsToRemote(branchURL, credentials);
// this.gitInstance(repository.directory).raw(
// [
// // `${urlRemote}`
// 'push',
// `--repo=${ urlRemote }`,
// '--all'
// ]
// ).then(r => console.log(r));
return this.gitInstance(repository.directory).push().then(() => {
console.log('push complete');
return true;
});
push(directory, branchName, remoteType = 'origin', options?: { [key: string]: null | string | any }) {
return this.gitInstance(directory).push(
remoteType,
branchName,
options
);
}

/**
* For pushing new branch to remote
* @param directory
* @param branchName
* @param remoteType
* @param options
*/
pushUpStream(directory: string, branchName: string, remoteType = 'origin', options?: { [key: string]: null | string | any }) {
const defaultOptions = {
'-u': null // Upstream
};
if (options && Object.keys(options).length > 0) {
Object.assign(defaultOptions, options);
}
return this.gitInstance(directory)
.push(
remoteType,
branchName,
defaultOptions
);
}

/**
Expand All @@ -315,6 +318,25 @@ export class GitService {
return instanceGit.commit(message, fileList, option);
}

/**
* Status: Done
* @param repository
* @param branchName
* @param credentials
*/
async switchBranch(repository: Repository, branchName: string, credentials?: Account) {
if (!this.isGitProject(repository.directory)) {
return false;
}

return await this.gitInstance(repository.directory).checkout(branchName)
.then(resolve => true)
.catch(err => {
console.log(err);
return false;
});
}

async revert(repository: Repository, files: string[]) {
if (files.length === 0) {
// reset hard
Expand Down Expand Up @@ -356,18 +378,6 @@ export class GitService {
]);
}

async switchBranch(repository: Repository, branch: RepositoryBranchSummary, credentials?: Account) {
if (!this.isGitProject(repository.directory)) {
return false;
}

return await this.gitInstance(repository.directory).checkout(branch.name)
.then(resolve => true)
.catch(err => {
console.log(err);
return false;
});
}

async isFileIgnored(repository: Repository, ...filePath: string[]) {
return this.gitInstance(repository.directory)
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
<p>yes-no-decision works!</p>
<h2 class="weight-lighter m-0 mb-2">
{{emittedDataFromView.title}}
</h2>
<p class="mt-0 mb-2 body text-muted">
{{emittedDataFromView.body}}
</p>
<div class="decision">
<button (click)="closeDialog(false)"
class="bg-primary-black-darker"
mat-flat-button>
{{emittedDataFromView.decision.noText}}
</button>
<button (click)="closeDialog(true)"
color="primary"
mat-raised-button>
{{emittedDataFromView.decision.yesText}}
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import "src/styles/theme";

:host {
display: flex;
flex-direction: column;
}

.decision {
display: flex;
justify-content: flex-end;

> *:not(:last-child) {
margin-right: 0.5rem;
}
}

.body {
font-size: 0.8rem;
}
Loading