remote branches

git4refactor
filip mertens 7 months ago
parent aa7d58bad1
commit d843e5c036
  1. 8
      apps/remix-ide/src/app/files/dgitProvider.ts
  2. 2
      libs/remix-ui/git/src/components/buttons/gituibutton.tsx
  3. 39
      libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx
  4. 9
      libs/remix-ui/git/src/components/navigation/branchedetails.tsx
  5. 7
      libs/remix-ui/git/src/components/panels/commands/fetch.tsx
  6. 1
      libs/remix-ui/git/src/components/panels/commands/merge.tsx
  7. 20
      libs/remix-ui/git/src/components/panels/commands/pushpull.tsx
  8. 5
      libs/remix-ui/git/src/components/panels/commits.tsx
  9. 2
      libs/remix-ui/git/src/components/panels/remotes.tsx
  10. 81
      libs/remix-ui/git/src/lib/gitactions.ts
  11. 2
      libs/remix-ui/git/src/lib/listeners.ts
  12. 12
      libs/remix-ui/git/src/state/gitpayload.ts
  13. 9
      libs/remix-ui/git/src/state/gitreducer.tsx

@ -303,14 +303,14 @@ class DGitProvider extends Plugin {
}
async getCommitChanges(commitHash1, commitHash2): Promise<commitChange[]> {
//console.log([git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })])
console.log(commitHash1, commitHash2, [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })])
const result: commitChange[] = await git.walk({
...await this.addIsomorphicGitConfigFS(),
trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })],
map: async function (filepath, [A, B]) {
// ignore directories
//console.log(filepath, A, B)
console.log(filepath, A, B)
if (filepath === '.') {
return
@ -333,6 +333,8 @@ class DGitProvider extends Plugin {
path: filepath,
}
console.log('Aoid', Aoid, 'Boid', Boid, commitChange)
// determine modification type
if (Aoid !== Boid) {
commitChange.type = "modified"
@ -340,7 +342,7 @@ class DGitProvider extends Plugin {
if (Aoid === undefined) {
commitChange.type = "deleted"
}
if (Boid === undefined) {
if (Boid === undefined || !commitHash2) {
commitChange.type = "added"
}
if (Aoid === undefined && Boid === undefined) {

@ -15,7 +15,7 @@ const GitUIButton = ({children, disabledCondition = false, ...rest }:ButtonWithC
const isDisabled = loading || disabledCondition
return (
<button disabled={loading} {...rest}>
<button disabled={isDisabled} {...rest}>
{children}
</button>
);

@ -50,7 +50,7 @@ export const SourceControlButtons = (props: SourceControlButtonsProps) => {
}
if (!props.remote) {
setRemote(context.defaultRemote)
}else{
} else {
setDefaultRemote()
}
}, [])
@ -62,7 +62,7 @@ export const SourceControlButtons = (props: SourceControlButtonsProps) => {
}
if (!props.remote) {
setRemote(context.defaultRemote)
}else{
} else {
setDefaultRemote()
}
}, [context.defaultRemote, context.currentBranch])
@ -86,19 +86,26 @@ export const SourceControlButtons = (props: SourceControlButtonsProps) => {
await actions.push(remote.remote, branch.name)
}
const buttonsDisabled = () => {
return context.upstream === '' || context.remotes.length === 0
}
return (<span className='d-flex justify-content-end align-items-center'>
<CustomTooltip tooltipText={<FormattedMessage id="git.pull" />}>
<>{commitsBehind.length}<GitUIButton onClick={pull} className='btn btn-sm'><FontAwesomeIcon icon={faArrowDown} className="" /></GitUIButton></>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.push" />}>
<>{commitsAhead.length}<GitUIButton onClick={push} className='btn btn-sm'><FontAwesomeIcon icon={faArrowUp} className="" /></GitUIButton></>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.sync" />}>
<GitUIButton onClick={sync} className='btn btn-sm'><FontAwesomeIcon icon={faArrowsUpDown} className="" /></GitUIButton>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.refresh" />}>
<GitUIButton onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowRotateRight} className="" /></GitUIButton>
</CustomTooltip>
</span>)
return (
<span className='d-flex justify-content-end align-items-center'>
<CustomTooltip tooltipText={<FormattedMessage id="git.pull" />}>
<>{commitsBehind.length}<GitUIButton disabledCondition={buttonsDisabled()} onClick={pull} className='btn btn-sm'><FontAwesomeIcon icon={faArrowDown} className="" /></GitUIButton></>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.push" />}>
<>{commitsAhead.length}<GitUIButton disabledCondition={buttonsDisabled()} onClick={push} className='btn btn-sm'><FontAwesomeIcon icon={faArrowUp} className="" /></GitUIButton></>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.sync" />}>
<GitUIButton disabledCondition={buttonsDisabled()} onClick={sync} className='btn btn-sm'><FontAwesomeIcon icon={faArrowsUpDown} className="" /></GitUIButton>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.refresh" />}>
<GitUIButton disabledCondition={buttonsDisabled()} onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowRotateRight} className="" /></GitUIButton>
</CustomTooltip>
</span>
)
}

@ -1,6 +1,7 @@
import { faCaretUp, faCaretDown, faCaretRight, faArrowUp, faArrowDown, faArrowRotateRight, faArrowsUpDown, faGlobe, faCheckCircle, faToggleOff, faToggleOn, faSync } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useContext, useEffect } from "react";
import { gitActionsContext } from "../../state/context";
import { branch } from "../../types";
import { gitPluginContext } from "../gitui";
@ -15,6 +16,7 @@ interface BrancheDetailsNavigationProps {
export const BrancheDetailsNavigation = (props: BrancheDetailsNavigationProps) => {
const { eventKey, activePanel, callback, branch, checkout } = props;
const context = React.useContext(gitPluginContext)
const actions = React.useContext(gitActionsContext)
const handleClick = () => {
if (!callback) return
if (activePanel === eventKey) {
@ -28,6 +30,10 @@ export const BrancheDetailsNavigation = (props: BrancheDetailsNavigationProps) =
window.open(`${branch.remote.url}/tree/${branch.name}`, '_blank');
}
const reloadBranch = () => {
actions.getBranchCommits(branch, 1)
}
return (
<>
<div className="d-flex flex-row w-100 mb-2 mt-2">
@ -45,6 +51,9 @@ export const BrancheDetailsNavigation = (props: BrancheDetailsNavigationProps) =
<FontAwesomeIcon className='ml-auto mr-1 pointer' icon={faToggleOn} onClick={() => checkout(branch)}></FontAwesomeIcon>
}
{branch.remote?.url && <>
<FontAwesomeIcon className='ml-2 pointer' icon={faSync} onClick={() => reloadBranch()}></FontAwesomeIcon></>}
{branch.remote?.url && <>
<FontAwesomeIcon className='ml-2 pointer' icon={faGlobe} onClick={() => openRemote()}></FontAwesomeIcon></>}
</div>

@ -8,11 +8,14 @@ export const Fetch = () => {
const actions = React.useContext(gitActionsContext)
const context = React.useContext(gitPluginContext)
const fetchIsDisabled = () => {
return context.upstream === '' || context.remotes.length === 0
}
return (
<>
<div className="btn-group w-100" role="group">
<GitUIButton type="button" onClick={async () => actions.fetch()} className="btn btn-primary mr-1">Fetch {context.upstream}</GitUIButton>
<GitUIButton type="button" onClick={async () => actions.fetch(null, null, context.currentBranch.name, null, true )} className="btn btn-primary">Fetch {context.currentBranch.name}</GitUIButton>
<GitUIButton disabledCondition={fetchIsDisabled()} type="button" onClick={async () => actions.fetch()} className="btn btn-primary mr-1">Fetch {context.upstream}</GitUIButton>
<GitUIButton disabledCondition={fetchIsDisabled()} type="button" onClick={async () => actions.fetch(null, null, context.currentBranch.name, null, true )} className="btn btn-primary">Fetch {context.currentBranch.name}</GitUIButton>
</div>
</>)
}

@ -53,6 +53,7 @@ export const Merge = () => {
<label>Merge from Branch</label>
<Select
options={localBranchOptions}
isDisabled={context.branches.length === 0}
onChange={(e: any) => e && onLocalBranchChange(e.value)}
theme={selectTheme}
styles={selectStyles}

@ -36,12 +36,12 @@ export const PushPull = () => {
}
const onRemoteChange = (value: any) => {
console.log('onRemoteChange', value)
console.log('onRemoteChange', value, context)
actions.setUpstreamRemote(value)
}
useEffect(() => {
console.log('UPSTREAM', context.upstream)
console.log('UPSTREAM', context.upstream, context)
}, [context.upstream])
const onForceChange = (event: any) => {
@ -61,7 +61,7 @@ export const PushPull = () => {
useEffect(() => {
console.log('context repositories', context.repositories)
console.log('context branches', context.branches)
// map context.repositories to options
const localBranches = context.branches && context.branches.length > 0 && context.branches
.filter(branch => !branch.remote)
@ -93,6 +93,11 @@ export const PushPull = () => {
}, [context.remotes])
const pushPullIsDisabled = () => {
return localBranch === '' || remoteBranch === '' || context.upstream === '' || context.remotes.length === 0
}
return (
<>
@ -100,14 +105,15 @@ export const PushPull = () => {
<div className="btn-group w-100" role="group">
<GitUIButton type="button" onClick={async () => pull()} className="btn btn-primary mr-1">Pull</GitUIButton>
<GitUIButton type="button" onClick={async () => push()} className="btn btn-primary">Push</GitUIButton>
<GitUIButton disabledCondition={pushPullIsDisabled()} type="button" onClick={async () => pull()} className="btn btn-primary mr-1">Pull</GitUIButton>
<GitUIButton disabledCondition={pushPullIsDisabled()} type="button" onClick={async () => push()} className="btn btn-primary">Push</GitUIButton>
</div>
<label>Local Branch</label>
<Select
options={localBranchOptions}
isDisabled={context.branches.length === 0}
onChange={(e: any) => e && onLocalBranchChange(e.value)}
theme={selectTheme}
styles={selectStyles}
@ -119,6 +125,7 @@ export const PushPull = () => {
<label>Remote Branch</label>
<Select
options={remoteBranchOptions}
isDisabled={context.branches.length === 0}
onChange={(e: any) => e && onRemoteBranchChange(e.value)}
theme={selectTheme}
styles={selectStyles}
@ -127,9 +134,10 @@ export const PushPull = () => {
placeholder="Type to search for a branch..."
/>
<label>Upstream</label>
<label>Remote</label>
<Select
options={localRemotesOptions}
isDisabled={context.remotes.length === 0}
onChange={(e: any) => e && onRemoteChange(e.value)}
theme={selectTheme}
styles={selectStyles}

@ -34,6 +34,9 @@ export const Commits = () => {
await actions.getCommitChanges(commit.oid, commit.commit.parent[0])
}
const fetchIsDisabled = () => {
return context.upstream === '' || context.remotes.length === 0
}
return (
<>
@ -47,7 +50,7 @@ export const Commits = () => {
})}
</div>
</div>
{hasNextPage && <GitUIButton className="mb-1 ml-2 btn btn-sm" onClick={loadNextPage}>Load more</GitUIButton>}
{hasNextPage && <GitUIButton disabledCondition={fetchIsDisabled()} className="mb-1 ml-2 btn btn-sm" onClick={loadNextPage}>Load more</GitUIButton>}
</>
: <div className="text-muted">No commits</div>}
</>

@ -48,7 +48,7 @@ export const Remotes = () => {
<input placeholder="remote name" name='remotename' onChange={e => onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-2" type="text" id="remotename" />
<input placeholder="remote url" name='remoteurl' onChange={e => onUrlChange(e.target.value)} value={url} className="form-control" type="text" id="remoteurl" />
<button className='btn btn-primary mt-1 w-100' onClick={async () => {
<button disabled={(remoteName && url)?false:true} className='btn btn-primary mt-1 w-100' onClick={async () => {
addRemote();
}}>add remote</button>
<hr />

@ -1,7 +1,7 @@
import { ViewPlugin } from "@remixproject/engine-web";
import { ReadBlobResult, ReadCommitResult } from "isomorphic-git";
import React from "react";
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog } from "../state/gitpayload";
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog } from "../state/gitpayload";
import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog } from '../types';
import { removeSlash } from "../utils";
import { disableCallBacks, enableCallBacks } from "./listeners";
@ -381,7 +381,7 @@ export const fetch = async (remote?: string, ref?: string, remoteRef?: string, d
await plugin.call('notification', 'toast', `Fetching ${remote || ''} ${ref || ''} ${remoteRef || ''}`)
try {
await plugin.call('dGitProvider' as any, 'fetch', { remote, ref, remoteRef, depth, singleBranch, relative });
if(!quiet){
if (!quiet) {
await gitlog()
await getBranches()
}
@ -428,6 +428,7 @@ const tokenWarning = async () => {
const parseError = async (e: any) => {
console.log(e)
// if message conttains 401 Unauthorized, show token warning
if (e.message.includes('401')) {
const result = await plugin.call('notification', 'modal', {
@ -458,6 +459,13 @@ const parseError = async (e: any) => {
cancelLabel: 'Close',
type: ModalTypes.confirm
})
} else if (e.toString().includes('NotFoundError') && !e.toString().includes('fetch')) {
await plugin.call('notification', 'modal', {
title: 'Remote branch not found',
message: 'The branch you are trying to fetch does not exist on the remote.\ If you have forked this branch from another branch, you may need to fetch the original branch first or publish this branch on the remote.',
okLabel: 'OK',
type: ModalTypes.alert
})
} else {
await plugin.call('notification', 'alert', {
title: 'Error',
@ -475,12 +483,12 @@ export const repositories = async () => {
let page = 2
let hasMoreData = true
const per_page = 100
while(hasMoreData){
let pagedResponse = await plugin.call('dGitProvider' as any, 'repositories', { token, page:page, per_page: per_page })
if(pagedResponse.length < per_page){
while (hasMoreData) {
let pagedResponse = await plugin.call('dGitProvider' as any, 'repositories', { token, page: page, per_page: per_page })
if (pagedResponse.length < per_page) {
hasMoreData = false
}
repos = [...repos,...pagedResponse]
repos = [...repos, ...pagedResponse]
dispatch(setRepos(repos))
page++
}
@ -511,12 +519,12 @@ export const remoteBranches = async (owner: string, repo: string) => {
let page = 2
let hasMoreData = true
const per_page = 100
while(hasMoreData){
let pagedResponse = await plugin.call('dGitProvider' as any, 'remotebranches', { token, owner, repo, page:page, per_page: per_page })
if(pagedResponse.length < per_page){
while (hasMoreData) {
let pagedResponse = await plugin.call('dGitProvider' as any, 'remotebranches', { token, owner, repo, page: page, per_page: per_page })
if (pagedResponse.length < per_page) {
hasMoreData = false
}
branches = [...branches,...pagedResponse]
branches = [...branches, ...pagedResponse]
dispatch(setRemoteBranches(branches))
page++
}
@ -736,11 +744,22 @@ export const diff = async (commitChange: commitChange) => {
export const getCommitChanges = async (oid1: string, oid2: string, branch?: branch, remote?: remote) => {
console.log(oid1, oid2, branch, remote)
try{
try {
// check if oid2 exists
const log = await plugin.call('dGitProvider', 'log', {
ref: branch? branch.name : 'HEAD',
})
if(log) {
const foundCommit = log.find((commit: ReadCommitResult) => commit.oid === oid2)
if(!foundCommit) {
await fetch(remote? remote.remote: null, branch? branch.name: null,null, 5, true, true)
}
}
const result: commitChange[] = await plugin.call('dGitProvider', 'getCommitChanges', oid1, oid2)
dispatch(setCommitChanges(result))
return result
}catch(e){
} catch (e) {
console.log(e)
return false
}
@ -759,9 +778,12 @@ async function getRepoDetails(url: string) {
export const fetchBranch = async (branch: branch, page: number) => {
if(!branch.remote || !branch.remote.url) return
if (!branch.remote || !branch.remote.url) return
const token = await tokenWarning();
console.log('fetch', branch)
if (page == 1) {
dispatch(resetRemoteBranchCommits({ branch }))
}
const { owner, repo } = await getRepoDetails(branch.remote.url);
const rc = await plugin.call('dGitProvider' as any, 'remotecommits', { token, owner: owner, repo: repo, branch: branch.name, length, page });
console.log(rc, 'remote commits from octokit')
@ -825,28 +847,31 @@ export const getBranchCommits = async (branch: branch, page: number) => {
const commits: ReadCommitResult[] = await plugin.call('dGitProvider', 'log', {
ref: branch.name,
})
const branchDifference: branchDifference = await plugin.call('dGitProvider', 'compareBranches', {
branch,
remote: {
remote: 'origin',
url: ''
}
})
console.log(commits, branchDifference)
dispatch(setBranchDifferences(
{
try {
const branchDifference: branchDifference = await plugin.call('dGitProvider', 'compareBranches', {
branch,
remote:
{ remote: 'origin', url: '' },
remote: {
remote: 'origin',
url: ''
}
})
console.log(commits, branchDifference)
dispatch(setBranchDifferences(
{
branch,
remote:
{ remote: 'origin', url: '' },
branchDifference: branchDifference
}))
}))
} catch (e) {
}
dispatch(setLocalBranchCommits({ branch, commits }))
} else {
await fetchBranch(branch, page)
}
} catch (e) {
console.log(e)
console.trace(e)
await fetchBranch(branch, page)
}
dispatch(setLoading(false))

@ -196,7 +196,7 @@ export const enableCallBacks = async () => {
}
const synTimerStart = async () => {
console.trace('synTimerStart')
//console.trace('synTimerStart')
if (!callBackEnabled) return
clearTimeout(syncTimer)
syncTimer = setTimeout(async () => {

@ -142,6 +142,18 @@ export const setRemoteBranchCommits = ({ branch, commits }:{
}
}
export const resetRemoteBranchCommits = ({ branch }:{
branch: branch,
}):{
type: string;
payload: { branch: branch };
} => {
return {
type: 'RESET_REMOTE_BRANCH_COMMITS',
payload: { branch }
}
}
export const setLocalBranchCommits = ({
branch,
commits

@ -119,6 +119,15 @@ export const gitReducer = (state: gitState = defaultGitState, action: Action): g
commitChanges: [...state.commitChanges]
}
case 'RESET_REMOTE_BRANCH_COMMITS':
if (state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name]) {
delete state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name]
}
return {
...state,
remoteBranchCommits: { ...state.remoteBranchCommits }
}
case 'SET_REMOTE_BRANCH_COMMITS':
if (state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name]) {
state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name].push(...(action as setRemoteBranchCommitsAction).payload.commits)

Loading…
Cancel
Save