From ede22d886a220cbe8dcb1f74088d2cdf640f1aa1 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Fri, 19 Apr 2024 10:48:29 +0200 Subject: [PATCH] branch diffs --- apps/remix-ide/src/app/files/dgitProvider.ts | 31 ++++- libs/remix-ui/git/src/components/gitui.tsx | 16 +-- .../git/src/components/navigation/commits.tsx | 32 +++++- .../components/navigation/remotesdetails.tsx | 2 +- .../git/src/components/panels/branches.tsx | 7 +- .../panels/branches/branchCommits.tsx | 108 ------------------ .../panels/branches/branchdifferences.tsx | 47 ++++++++ .../panels/branches/localbranchdetails.tsx | 77 +++++++++++++ ...hedetails.tsx => remotebranchedetails.tsx} | 3 +- .../src/components/panels/remoteselect.tsx | 4 +- libs/remix-ui/git/src/lib/gitactions.ts | 25 +++- libs/remix-ui/git/src/state/gitpayload.ts | 36 +++++- libs/remix-ui/git/src/state/gitreducer.tsx | 48 ++++---- libs/remix-ui/git/src/types/index.ts | 40 +++++-- 14 files changed, 306 insertions(+), 170 deletions(-) delete mode 100644 libs/remix-ui/git/src/components/panels/branches/branchCommits.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx rename libs/remix-ui/git/src/components/panels/branches/{branchedetails.tsx => remotebranchedetails.tsx} (96%) diff --git a/apps/remix-ide/src/app/files/dgitProvider.ts b/apps/remix-ide/src/app/files/dgitProvider.ts index e186f4f663..29457d21db 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.ts +++ b/apps/remix-ide/src/app/files/dgitProvider.ts @@ -35,7 +35,7 @@ const profile: LibraryProfile = { icon: 'assets/img/fileManager.webp', version: '0.0.1', methods: ['init', 'localStorageUsed', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'reset', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pull', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'version', 'updateSubmodules' - , 'getGitHubUser', 'remotebranches', 'remotecommits', 'repositories', 'getCommitChanges'], + , 'getGitHubUser', 'remotebranches', 'remotecommits', 'repositories', 'getCommitChanges', 'compareBranches'], kind: 'file-system' } class DGitProvider extends Plugin { @@ -273,6 +273,35 @@ class DGitProvider extends Plugin { return status } + async compareBranches({branch, remote}:{branch: branch, remote: remote}) { + // Get current branch commits + const headCommits = await git.log({ + ...await this.addIsomorphicGitConfigFS(), + ref: branch.name, + }); + + // Get remote branch commits + const remoteCommits = await git.log({ + ...await this.addIsomorphicGitConfigFS(), + ref: `${remote.remote}/${branch.name}`, + }); + + // Convert arrays of commit objects to sets of commit SHAs + const headCommitSHAs = new Set(headCommits.map(commit => commit.oid)); + const remoteCommitSHAs = new Set(remoteCommits.map(commit => commit.oid)); + + // Filter out commits that are only in the remote branch + const uniqueRemoteCommits = remoteCommits.filter(commit => !headCommitSHAs.has(commit.oid)); + + // filter out commits that are only in the local branch + const uniqueHeadCommits = headCommits.filter(commit => !remoteCommitSHAs.has(commit.oid)); + + return { + uniqueHeadCommits, + uniqueRemoteCommits, + }; + } + async getCommitChanges(commitHash1, commitHash2): Promise { //console.log([git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })]) const result: commitChange[] = await git.walk({ diff --git a/libs/remix-ui/git/src/components/gitui.tsx b/libs/remix-ui/git/src/components/gitui.tsx index d788b13c78..ca34ae2548 100644 --- a/libs/remix-ui/git/src/components/gitui.tsx +++ b/libs/remix-ui/git/src/components/gitui.tsx @@ -12,7 +12,7 @@ import { Commits } from './panels/commits' import { Branches } from './panels/branches' import { SourceControlNavigation } from './navigation/sourcecontrol' import { BranchesNavigation } from './navigation/branches' -import { CommitslNavigation } from './navigation/commits' +import { CommitsNavigation } from './navigation/commits' import '../style/index.css' import { CloneNavigation } from './navigation/clone' import { Clone } from './panels/clone' @@ -149,7 +149,7 @@ export const GitUI = (props: IGitUi) => {
- + <> @@ -162,12 +162,6 @@ export const GitUI = (props: IGitUi) => {
- - - <> - - -
<> @@ -175,6 +169,12 @@ export const GitUI = (props: IGitUi) => {
+ + + <> + + +
<> diff --git a/libs/remix-ui/git/src/components/navigation/commits.tsx b/libs/remix-ui/git/src/components/navigation/commits.tsx index 8d07175748..b34f7f4870 100644 --- a/libs/remix-ui/git/src/components/navigation/commits.tsx +++ b/libs/remix-ui/git/src/components/navigation/commits.tsx @@ -1,12 +1,25 @@ import { faCaretDown, faArrowUp, faArrowDown, faArrowRotateRight, faCaretRight, faArrowsUpDown } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { CustomTooltip } from "@remix-ui/helper"; -import React, { } from "react"; +import React, { useEffect } from "react"; import { FormattedMessage } from "react-intl"; import { pluginActionsContext } from "../../state/context"; +import { gitPluginContext } from "../gitui"; -export const CommitslNavigation = ({ eventKey, activePanel, callback }) => { +export interface CommitsNavigationProps { + title: string, + eventKey: string, + activePanel: string, + callback: (eventKey: string) => void +} + +export const CommitsNavigation = ({ eventKey, activePanel, callback, title }: CommitsNavigationProps) => { const pluginactions = React.useContext(pluginActionsContext) + const [pullEnabled, setPullEnabled] = React.useState(true) + const [pushEnabled, setPushEnabled] = React.useState(true) + const [syncEnabled, setSyncEnabled] = React.useState(false) + const [fetchEnabled, setFetchEnabled] = React.useState(true) + const context = React.useContext(gitPluginContext) const handleClick = () => { if (!callback) return @@ -24,22 +37,29 @@ export const CommitslNavigation = ({ eventKey, activePanel, callback }) => { { activePanel === eventKey ? : } - + { activePanel === eventKey ? + {pullEnabled ? }> - + : null} + {pushEnabled ? }> - + : null} + {syncEnabled ? }> - + : null} + {fetchEnabled ? + }> + + : null} : null } diff --git a/libs/remix-ui/git/src/components/navigation/remotesdetails.tsx b/libs/remix-ui/git/src/components/navigation/remotesdetails.tsx index 60ef11aa17..7d59cd68d3 100644 --- a/libs/remix-ui/git/src/components/navigation/remotesdetails.tsx +++ b/libs/remix-ui/git/src/components/navigation/remotesdetails.tsx @@ -34,7 +34,7 @@ export const RemotesDetailsNavigation = (props: RemotesDetailsNavigationProps) = { activePanel === eventKey ? : } -
+
{remote.remote} {remote.url}
diff --git a/libs/remix-ui/git/src/components/panels/branches.tsx b/libs/remix-ui/git/src/components/panels/branches.tsx index b655e1f5fa..c45e0304b4 100644 --- a/libs/remix-ui/git/src/components/panels/branches.tsx +++ b/libs/remix-ui/git/src/components/panels/branches.tsx @@ -3,7 +3,8 @@ import { Alert } from "react-bootstrap"; import { gitActionsContext } from "../../state/context"; import { remote } from "../../types"; import { gitPluginContext } from "../gitui"; -import { BranchDetails } from "./branches/branchedetails"; +import { LocalBranchDetails } from "./branches/localbranchdetails"; +import { RemoteBranchDetails } from "./branches/remotebranchedetails"; export const Branches = () => { const context = React.useContext(gitPluginContext) @@ -26,9 +27,9 @@ export const Branches = () => {
{context.branches && context.branches.length ?
- {context.branches && context.branches.map((branch, index) => { + {context.branches && context.branches.filter((branch, index) => !branch.remote).map((branch, index) => { return ( - + ); })}
diff --git a/libs/remix-ui/git/src/components/panels/branches/branchCommits.tsx b/libs/remix-ui/git/src/components/panels/branches/branchCommits.tsx deleted file mode 100644 index e30db28c2c..0000000000 --- a/libs/remix-ui/git/src/components/panels/branches/branchCommits.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import React, { useEffect } from 'react'; -import { gql, useQuery } from '@apollo/client'; - -const GET_COMMITS = gql(/* GraphQL */` - query GetCommits($name: String!, $owner: String!, $cursor: String, $limit: Int = 10) { - repository(name: $name, owner: $owner) { - ref(qualifiedName: "master") { - target { - ... on Commit { - history(first: $limit, after: $cursor) { - pageInfo { - endCursor - hasNextPage - } - edges { - node { - oid - messageHeadline - message - committedDate - author { - name - email - date - } - parents(first: 1) { - edges { - node { - oid - } - } - } - tree { - oid - } - } - } - } - } - } - } - } - } -`); - - -export const BranchCommits = ({ owner, name }) => { - const { data, loading, fetchMore } = useQuery(GET_COMMITS, { - variables: { owner, name }, - }); - - if (loading) return

Loading...

; - - const { edges, pageInfo } = (data.repository.ref.target.__typename === "Commit")? data.repository.ref.target.history : { edges: [], pageInfo: { endCursor: null, hasNextPage: false } }; - - const loadNextPage= ()=>{ - fetchMore({ - variables: { - cursor: pageInfo.endCursor, - }, - updateQuery: (prevResult, { fetchMoreResult }) => { - const newEdges = (fetchMoreResult.repository.ref.target.__typename === "Commit"? fetchMoreResult.repository.ref.target.history.edges : []) - const pageInfo = (fetchMoreResult.repository.ref.target.__typename === "Commit"? fetchMoreResult.repository.ref.target.history.pageInfo : {}) - - return newEdges.length && prevResult.repository.ref.target.__typename === "Commit" - ? { - repository: { - __typename: prevResult.repository.__typename, - ref: { - __typename: prevResult.repository.ref.__typename, - target: { - __typename: prevResult.repository.ref.target.__typename, - history: { - __typename: prevResult.repository.ref.target.history.__typename, - edges: [...prevResult.repository.ref.target.history.edges, ...newEdges], - pageInfo, - }, - }, - }, - }, - } as any - : prevResult; - }, - }); - } - - return ( -
-
    - {edges.map(({ node }) => { - console.log(node) - return( -
  • -

    {node.messageHeadline} - {node.author.name} ({new Date(node.author.date).toLocaleDateString()})

    -
  • - ) - })} -
- {pageInfo.hasNextPage && ( - - )} -
- ); -}; diff --git a/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx b/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx new file mode 100644 index 0000000000..c305687c53 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx @@ -0,0 +1,47 @@ +import { branch, remote } from "../../../types"; +import React, { useEffect, useState } from "react"; +import { gitPluginContext } from "../../gitui"; +import { CommitDetails } from "../commits/commitdetails"; + +export interface BrancheDetailsProps { + branch: branch; +} + +export const BranchDifferences = (props: BrancheDetailsProps) => { + const { branch } = props; + const context = React.useContext(gitPluginContext) + + useEffect(() => { + console.log('GET BRANCH DIFF', branch) + }, []) + + useEffect(() => { + console.log('BRANCH DIFF', context.branchDifferences) + }, [context.branchDifferences]) + + const commitsAhead = (remote: remote) => { + return context.branchDifferences[`${remote.remote}/${branch.name}`]?.uniqueHeadCommits || []; + } + + const commitsBehind = (remote: remote) => { + return context.branchDifferences[`${remote.remote}/${branch.name}`]?.uniqueRemoteCommits || []; + } + + return ( +
+
+ {context.remotes.map((remote, index) => { + return ( +
+
{remote.remote}
+
    +
  • ahead by {commitsAhead(remote).length} commit(s)
  • +
  • behind by {commitsBehind(remote).length} commits(s)
  • +
+
+ ); + })} +
+
+ ); +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx b/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx new file mode 100644 index 0000000000..b1976c8a5e --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx @@ -0,0 +1,77 @@ +import { ReadCommitResult } from "isomorphic-git" +import React, { useEffect, useState } from "react"; +import { Accordion } from "react-bootstrap"; +import { CommitDetailsNavigation } from "../../navigation/commitdetails"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { branch } from "../../../types"; +import { BrancheDetailsNavigation } from "../../navigation/branchedetails"; +import { CommitDetailsItems } from "../commits/commitdetailsitem"; +import { CommitDetails } from "../commits/commitdetails"; +import { BranchDifferences } from "./branchdifferences"; + +export interface BrancheDetailsProps { + branch: branch; +} + +export const LocalBranchDetails = (props: BrancheDetailsProps) => { + const { branch } = props; + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + const [activePanel, setActivePanel] = useState(""); + const [hasNextPage, setHasNextPage] = useState(false) + const [lastPageNumber, setLastPageNumber] = useState(0) + + useEffect(() => { + if (activePanel === "0") { + console.log('GET BRANCH COMMITS', branch) + if(lastPageNumber === 0) + actions.getBranchCommits(branch, 1) + } + }, [activePanel]) + + + + const checkout = (branch: branch) => { + actions.checkout({ + ref: branch.name, + remote: branch.remote && branch.remote.remote || null + }); + } + + const loadNextPage = () => { + console.log('LOAD NEXT PAGE', lastPageNumber+1) + actions.getBranchCommits(branch, lastPageNumber+1) + } + + const checkoutCommit = async (oid: string) => { + try { + //await ModalRef.current?.show(); + actions.checkout({ ref: oid }) + //Utils.log("yes"); + } catch (e) { + //Utils.log("no"); + } +}; + + return ( + + + <> +
+ + {context.localBranchCommits && Object.entries(context.localBranchCommits).map(([key, value]) => { + if(key == branch.name){ + return value.map((commit, index) => { + return() + }) + } + })} + + +
+ {hasNextPage && Load more} + +
+
) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/branchedetails.tsx b/libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx similarity index 96% rename from libs/remix-ui/git/src/components/panels/branches/branchedetails.tsx rename to libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx index 15c82d99ac..29adbc9511 100644 --- a/libs/remix-ui/git/src/components/panels/branches/branchedetails.tsx +++ b/libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx @@ -8,13 +8,12 @@ import { branch } from "../../../types"; import { BrancheDetailsNavigation } from "../../navigation/branchedetails"; import { CommitDetailsItems } from "../commits/commitdetailsitem"; import { CommitDetails } from "../commits/commitdetails"; -import { BranchCommits } from "./branchCommits"; export interface BrancheDetailsProps { branch: branch; } -export const BranchDetails = (props: BrancheDetailsProps) => { +export const RemoteBranchDetails = (props: BrancheDetailsProps) => { const { branch } = props; const actions = React.useContext(gitActionsContext) const context = React.useContext(gitPluginContext) diff --git a/libs/remix-ui/git/src/components/panels/remoteselect.tsx b/libs/remix-ui/git/src/components/panels/remoteselect.tsx index 3285f81304..27b349fd37 100644 --- a/libs/remix-ui/git/src/components/panels/remoteselect.tsx +++ b/libs/remix-ui/git/src/components/panels/remoteselect.tsx @@ -6,7 +6,7 @@ import { default as dateFormat } from "dateformat"; import { RemotesDetailsNavigation } from "../navigation/remotesdetails"; import { Accordion } from "react-bootstrap"; import { remote } from "../../types"; -import { BranchDetails } from "./branches/branchedetails"; +import { RemoteBranchDetails } from "./branches/remotebranchedetails"; export interface RemoteSelectProps { remote: remote @@ -36,7 +36,7 @@ export const Remoteselect = (props: RemoteSelectProps) => { <> {context.branches && context.branches.filter((branch, index) => branch.remote && branch.remote.remote === remote.remote ).map((branch, index) => { return ( - + ); })} diff --git a/libs/remix-ui/git/src/lib/gitactions.ts b/libs/remix-ui/git/src/lib/gitactions.ts index a9e76636cf..e7ec3f4ca2 100644 --- a/libs/remix-ui/git/src/lib/gitactions.ts +++ b/libs/remix-ui/git/src/lib/gitactions.ts @@ -1,8 +1,8 @@ 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 } from "../state/gitpayload"; -import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState } from '../types'; +import { fileStatus, fileStatusMerge, setRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRateLimit, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences } from "../state/gitpayload"; +import { GitHubUser, RateLimit, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference } from '../types'; import { removeSlash } from "../utils"; import { disableCallBacks, enableCallBacks } from "./listeners"; import { AlertModal, ModalTypes } from "@remix-ui/app"; @@ -762,7 +762,7 @@ export const fetchBranch = async (branch: branch, page: number) => { console.log(mergeCommits) //console.log(r, commits) - dispatch(setRemoteBranchCommits({ branch, commits: mergeCommits })) + //dispatch(setRemoteBranchCommits({ branch, commits: mergeCommits })) } export const getBranchCommits = async (branch: branch, page: number) => { @@ -772,8 +772,23 @@ export const getBranchCommits = async (branch: branch, page: number) => { const commits: ReadCommitResult[] = await plugin.call('dGitProvider', 'log', { ref: branch.name, }) - console.log(commits) - //dispatch(setRemoteBranchCommits({ branch, commits })) + + const branchDifference: branchDifference = await plugin.call('dGitProvider', 'compareBranches', { + branch, + remote: { + remote: 'origin', + url: '' + } + }) + console.log(commits, branchDifference) + dispatch(setBranchDifferences( + { + branch, + remote: + { remote: 'origin', url: '' }, + branchDifference: branchDifference + })) + dispatch(setLocalBranchCommits({ branch, commits })) } else { await fetchBranch(branch, page) } diff --git a/libs/remix-ui/git/src/state/gitpayload.ts b/libs/remix-ui/git/src/state/gitpayload.ts index 910fa690d7..4a9b7eae9d 100644 --- a/libs/remix-ui/git/src/state/gitpayload.ts +++ b/libs/remix-ui/git/src/state/gitpayload.ts @@ -1,5 +1,5 @@ import { ReadCommitResult } from "isomorphic-git" -import { GitHubUser, branch, commitChange, fileStatusResult, remote } from "../types" +import { GitHubUser, branch, commitChange, fileStatusResult, remote, pagedCommits, branchDifference } from "../types" import { Endpoints } from "@octokit/types" export const fileStatus = (files: fileStatusResult[]) => { @@ -122,17 +122,47 @@ export const setCommitChanges = (commitChanges: commitChange[]) => { } } -export const setRemoteBranchCommits =({branch, commits}) => { +export const setRemoteBranchCommits = ({ branch, commits }:{ + branch: branch, + commits: pagedCommits[] +}):{ + type: string; + payload: { branch: branch; commits: pagedCommits[] }; +} => { return { type: 'SET_REMOTE_BRANCH_COMMITS', payload: { branch, commits } } } -export const setLocalBranchCommits = ({branch, commits}) => { +export const setLocalBranchCommits = ({ + branch, + commits +}: { + branch: branch; + commits: ReadCommitResult[]; +}): { + type: string; + payload: { branch: branch; commits: ReadCommitResult[] }; +} => { return { type: 'SET_LOCAL_BRANCH_COMMITS', payload: { branch, commits } + }; +}; + +export const setBranchDifferences = ({ + branch, + remote, + branchDifference +}:{ + branch: branch; + remote: remote; + branchDifference: branchDifference; +}) => { + return { + type: 'SET_BRANCH_DIFFERENCES', + payload: { branch, remote, branchDifference } } } diff --git a/libs/remix-ui/git/src/state/gitreducer.tsx b/libs/remix-ui/git/src/state/gitreducer.tsx index 1999e23c74..28976380dc 100644 --- a/libs/remix-ui/git/src/state/gitreducer.tsx +++ b/libs/remix-ui/git/src/state/gitreducer.tsx @@ -1,6 +1,6 @@ import { ReadCommitResult } from "isomorphic-git" import { allChangedButNotStagedFiles, getFilesByStatus, getFilesWithNotModifiedStatus } from "../lib/fileHelpers" -import { branch, commitChange, defaultGitState, fileStatusResult, gitState, setRemoteBranchCommitsAction, setLocalBranchCommitsAction } from "../types" +import { branch, commitChange, defaultGitState, fileStatusResult, gitState, setRemoteBranchCommitsAction, setLocalBranchCommitsAction, setBranchDifferencesAction } from "../types" interface Action { type: string @@ -10,7 +10,7 @@ interface Action { export const gitReducer = (state: gitState = defaultGitState, action: Action): gitState => { ///console.log(action, state) switch (action.type) { - + case 'FILE_STATUS': return { ...state, @@ -25,16 +25,17 @@ export const gitReducer = (state: gitState = defaultGitState, action: Action): g case 'FILE_STATUS_MERGE': const filesStatusResults: fileStatusResult[] = action.payload filesStatusResults.map((fileStatusResult: fileStatusResult) => { - const file = state.fileStatusResult.find( stateFile => { + const file = state.fileStatusResult.find(stateFile => { return stateFile.filename === fileStatusResult.filename }) - if(file){ + if (file) { file.status = fileStatusResult.status file.statusNames = fileStatusResult.statusNames } }) - - return {...state, + + return { + ...state, staged: getFilesByStatus("staged", state.fileStatusResult), modified: getFilesByStatus("modified", state.fileStatusResult), untracked: getFilesByStatus("untracked", state.fileStatusResult), @@ -54,13 +55,13 @@ export const gitReducer = (state: gitState = defaultGitState, action: Action): g ...state, branches: action.payload } - + case 'SET_CURRENT_BRANCH': return { ...state, currentBranch: action.payload } - + case 'SET_CAN_USE_APP': return { ...state, @@ -87,8 +88,8 @@ export const gitReducer = (state: gitState = defaultGitState, action: Action): g return { ...state, remoteBranches: action.payload - } - + } + case 'SET_CAN_COMMIT': return { ...state, @@ -119,25 +120,32 @@ export const gitReducer = (state: gitState = defaultGitState, action: Action): g } 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) - }else{ - state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name] = (action as setRemoteBranchCommitsAction).payload.commits + if (state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name]) { + state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name].push(...(action as setRemoteBranchCommitsAction).payload.commits) + } else { + state.remoteBranchCommits[(action as setRemoteBranchCommitsAction).payload.branch.name] = (action as setRemoteBranchCommitsAction).payload.commits } return { ...state, - remoteBranchCommits: {...state.remoteBranchCommits} + remoteBranchCommits: { ...state.remoteBranchCommits } } case 'SET_LOCAL_BRANCH_COMMITS': - if(state.localBranchCommits[(action as setLocalBranchCommitsAction).payload.branch.name]){ - state.localBranchCommits[(action as setLocalBranchCommitsAction).payload.branch.name].push(...(action as setLocalBranchCommitsAction).payload.commits) - }else{ - state.localBranchCommits[(action as setLocalBranchCommitsAction).payload.branch.name] = (action as setLocalBranchCommitsAction).payload.commits + + state.localBranchCommits[(action as setLocalBranchCommitsAction).payload.branch.name] = (action as setLocalBranchCommitsAction).payload.commits + return { + ...state, + localBranchCommits: { ...state.localBranchCommits } } + + case 'SET_BRANCH_DIFFERENCES': + + + state.branchDifferences[`${(action as setBranchDifferencesAction).payload.remote.remote}/${(action as setBranchDifferencesAction).payload.branch.name}`] = (action as setBranchDifferencesAction).payload.branchDifference + return { ...state, - localBranchCommits: {...state.localBranchCommits} + branchDifferences: { ...state.branchDifferences } } case 'SET_GITHUB_ACCESS_TOKEN': diff --git a/libs/remix-ui/git/src/types/index.ts b/libs/remix-ui/git/src/types/index.ts index bcb7f2719d..5c259c5053 100644 --- a/libs/remix-ui/git/src/types/index.ts +++ b/libs/remix-ui/git/src/types/index.ts @@ -25,8 +25,9 @@ export type gitState = { repositories: repository[] remoteBranches: remoteBranch[] commitChanges: commitChange[] - remoteBranchCommits: Record - localBranchCommits: Record + remoteBranchCommits: Record + localBranchCommits: Record + branchDifferences: Record syncStatus: syncStatus, localCommitCount: number remoteCommitCount: number @@ -36,6 +37,13 @@ export type gitState = { gitHubAccessToken: string } +export type remoteBranchIdentifier = `${string}/${string}` + +export type branchDifference = { + uniqueHeadCommits: ReadCommitResult[], + uniqueRemoteCommits: ReadCommitResult[], +} + export type pagedCommits = { page: number, perPage: number, @@ -52,7 +60,7 @@ export type loaderState = { plugin: boolean } -export type commitChangeTypes = { +export type commitChangeTypes = { "deleted": "D" "modified": "M" "added": "A", @@ -70,8 +78,8 @@ export type commitChangeType = keyof commitChangeTypes export type commitChange = { type: commitChangeType path: string, - hashModified : string, - hashOriginal : string, + hashModified: string, + hashOriginal: string, original?: string, modified?: string, readonly?: boolean @@ -124,6 +132,7 @@ export const defaultGitState: gitState = { commitChanges: [], remoteBranchCommits: {}, localBranchCommits: {}, + branchDifferences: {}, syncStatus: syncStatus.none, localCommitCount: 0, remoteCommitCount: 0, @@ -142,12 +151,12 @@ export const defaultLoaderState: loaderState = { } export type fileStatusResult = { - filename:string, + filename: string, status?: fileStatus - statusNames?:string[] + statusNames?: string[] } -export type fileStatus =[string, 0 | 1, 0 | 1 | 2, 0 | 1 | 2 | 3] +export type fileStatus = [string, 0 | 1, 0 | 1 | 2, 0 | 1 | 2 | 3] export type statusMatrixType = { matrix: string[] | undefined; status: string[] } @@ -156,7 +165,7 @@ export type sourceControlGroup = { name: string } -export interface fileStatusAction { +export interface fileStatusAction { type: string, payload: fileStatusResult[] } @@ -228,7 +237,16 @@ export interface setLocalBranchCommitsAction { type: string, payload: { branch: branch, - commits: pagedCommits[] + commits: ReadCommitResult[] + } +} + +export interface setBranchDifferencesAction { + type: string, + payload: { + branch: branch, + remote: remote, + branchDifference: branchDifference } } @@ -237,4 +255,4 @@ export interface setTokenAction { payload: string } -export type gitActionDispatch = setTokenAction | setUpstreamAction | setRemoteBranchCommitsAction | setLocalBranchCommitsAction | setRemotesAction | setCurrentBranchAction | fileStatusAction | setLoadingAction | setCanUseAppAction | setRepoNameAction | setCommitsAction | setBranchesAction | setReposAction | setRemoteBranchesAction \ No newline at end of file +export type gitActionDispatch = setTokenAction | setUpstreamAction | setRemoteBranchCommitsAction | setLocalBranchCommitsAction | setBranchDifferencesAction | setRemotesAction | setCurrentBranchAction | fileStatusAction | setLoadingAction | setCanUseAppAction | setRepoNameAction | setCommitsAction | setBranchesAction | setReposAction | setRemoteBranchesAction \ No newline at end of file