1
0
mirror of https://github.com/desktop/desktop synced 2024-06-30 22:54:41 +00:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Stephen Sigwart
f5d9883a11
Merge 83db3b646c into 7ca7c26111 2024-06-27 21:33:29 -04:00
Steve Ward
7ca7c26111
Merge pull request #18895 from desktop/gcm-integration-updates
Update integrations docs with new GCM support
2024-06-27 17:59:55 -04:00
Markus Olsson
d2c6ddb164
Merge pull request #18887 from desktop/args-args-everywhere
Inline argument conditionals
2024-06-27 09:27:16 +02:00
Steve Ward
d32900c3a2 These ones too 2024-06-26 14:17:23 -04:00
Steve Ward
376f9b642d Make screenshots a bit more compact 2024-06-26 14:12:00 -04:00
Steve Ward
ffc600a12d Add screenshots 2024-06-25 16:51:40 -04:00
Steve Ward
df4b2d35f3 Update integrations docs to showcase GCM 2024-06-25 14:34:47 -04:00
Markus Olsson
95f263a23d Set --progress and --recurse-submodules inline when necessary 2024-06-24 13:44:30 +02:00
Markus Olsson
10c3d47706 Set --progress and --recurse-submodules inline when necessary 2024-06-24 13:44:13 +02:00
Markus Olsson
8d86091ae3 🎨 Easier to read this way IMO 2024-06-24 13:43:48 +02:00
Markus Olsson
d8873cb08d Add --recurse-submodules and --progress inline when necessary 2024-06-24 13:43:14 +02:00
Markus Olsson
a404a3f251 Add --progress inline when necesary 2024-06-24 13:40:51 +02:00
Stephen Sigwart
83db3b646c
Fix staged file renamed with changes showing no diff
- Closes desktop/desktop#6014
- Fixes the case where a staged file is moved and modified. Previously, it would say it was moved with no changes.
2023-09-29 22:37:53 -04:00
16 changed files with 120 additions and 72 deletions

View File

@ -20,28 +20,22 @@ import { IRemote } from '../../models/remote'
export type ProgressCallback = (progress: ICheckoutProgress) => void
function getCheckoutArgs(progressCallback?: ProgressCallback) {
return progressCallback != null
? [...gitNetworkArguments(), 'checkout', '--progress']
: [...gitNetworkArguments(), 'checkout']
return [
...gitNetworkArguments(),
'checkout',
...(progressCallback ? ['--progress'] : []),
]
}
async function getBranchCheckoutArgs(branch: Branch) {
const baseArgs: ReadonlyArray<string> = []
if (enableRecurseSubmodulesFlag()) {
return branch.type === BranchType.Remote
? baseArgs.concat(
branch.name,
'-b',
branch.nameWithoutRemote,
'--recurse-submodules',
'--'
)
: baseArgs.concat(branch.name, '--recurse-submodules', '--')
}
return branch.type === BranchType.Remote
? baseArgs.concat(branch.name, '-b', branch.nameWithoutRemote, '--')
: baseArgs.concat(branch.name, '--')
return [
branch.name,
...(branch.type === BranchType.Remote
? ['-b', branch.nameWithoutRemote]
: []),
...(enableRecurseSubmodulesFlag() ? ['--recurse-submodules'] : []),
'--',
]
}
async function getCheckoutOpts(

View File

@ -485,8 +485,7 @@ export function gitRebaseArguments() {
// uses the merge backend even if the user has the apply backend
// configured, since this is the only one supported.
// This can go away once git deprecates the apply backend.
'-c',
'rebase.backend=merge',
...['-c', 'rebase.backend=merge'],
]
}

View File

@ -11,28 +11,16 @@ async function getFetchArgs(
remote: string,
progressCallback?: (progress: IFetchProgress) => void
) {
if (enableRecurseSubmodulesFlag()) {
return progressCallback != null
? [
...gitNetworkArguments(),
'fetch',
'--progress',
'--prune',
'--recurse-submodules=on-demand',
remote,
]
: [
...gitNetworkArguments(),
'fetch',
'--prune',
'--recurse-submodules=on-demand',
remote,
]
} else {
return progressCallback != null
? [...gitNetworkArguments(), 'fetch', '--progress', '--prune', remote]
: [...gitNetworkArguments(), 'fetch', '--prune', remote]
}
return [
...gitNetworkArguments(),
'fetch',
...(progressCallback ? ['--progress'] : []),
'--prune',
...(enableRecurseSubmodulesFlag()
? ['--recurse-submodules=on-demand']
: []),
remote,
]
}
/**

View File

@ -69,20 +69,24 @@ function mapStatus(
return { kind: AppFileStatusKind.Deleted, submoduleStatus }
} // deleted
if (status === 'R' && oldPath != null) {
return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus }
const renameIncludesModifications = false;
return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus, renameIncludesModifications }
} // renamed
if (status === 'C' && oldPath != null) {
return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus }
const renameIncludesModifications = false;
return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus, renameIncludesModifications }
} // copied
// git log -M --name-status will return a RXXX - where XXX is a percentage
if (status.match(/R[0-9]+/) && oldPath != null) {
return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus }
const renameIncludesModifications = (status !== "R100");
return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus, renameIncludesModifications }
}
// git log -C --name-status will return a CXXX - where XXX is a percentage
if (status.match(/C[0-9]+/) && oldPath != null) {
return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus }
const renameIncludesModifications = false;
return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus, renameIncludesModifications }
}
return { kind: AppFileStatusKind.Modified, submoduleStatus }

View File

@ -19,28 +19,15 @@ async function getPullArgs(
remote: string,
progressCallback?: (progress: IPullProgress) => void
) {
const divergentPathArgs = await getDefaultPullDivergentBranchArguments(
repository
)
const args = [
return [
...gitNetworkArguments(),
...gitRebaseArguments(),
'pull',
...divergentPathArgs,
...(await getDefaultPullDivergentBranchArguments(repository)),
...(enableRecurseSubmodulesFlag() ? ['--recurse-submodules'] : []),
...(progressCallback ? ['--progress'] : []),
remote,
]
if (enableRecurseSubmodulesFlag()) {
args.push('--recurse-submodules')
}
if (progressCallback != null) {
args.push('--progress')
}
args.push(remote)
return args
}
/**

View File

@ -163,12 +163,23 @@ function convertToAppStatus(
kind: AppFileStatusKind.Copied,
oldPath,
submoduleStatus: entry.submoduleStatus,
renameIncludesModifications: false,
}
} else if (entry.kind === 'renamed' && oldPath != null) {
// The renamed files includes modifications if the working tree has
// modifications of the rename score is not 100%.
let renameIncludesModifications = false;
if (
entry.workingTree === GitStatusEntry.Modified ||
(entry.renameOrCopyScore !== undefined && entry.renameOrCopyScore < 100)
) {
renameIncludesModifications = true;
}
return {
kind: AppFileStatusKind.Renamed,
oldPath,
submoduleStatus: entry.submoduleStatus,
renameIncludesModifications,
}
} else if (entry.kind === 'untracked') {
return {
@ -293,7 +304,7 @@ function buildStatusMap(
entry: IStatusEntry,
conflictDetails: ConflictFilesDetails
): Map<string, WorkingDirectoryFileChange> {
const status = mapStatus(entry.statusCode, entry.submoduleStatusCode)
const status = mapStatus(entry.statusCode, entry.submoduleStatusCode, entry.renameOrCopyScore)
if (status.kind === 'ordinary') {
// when a file is added in the index but then removed in the working

View File

@ -27,6 +27,9 @@ export interface IStatusEntry {
/** The original path in the case of a renamed file */
readonly oldPath?: string
/** The rename or copy score in the case of a renamed file */
readonly renameOrCopyScore?: number
}
export function isStatusHeader(
@ -140,6 +143,7 @@ function parsedRenamedOrCopiedEntry(
statusCode: match[1],
submoduleStatusCode: match[2],
oldPath,
renameOrCopyScore: parseInt(match[8].substring(1), 10),
path: match[9],
}
}
@ -195,7 +199,8 @@ function mapSubmoduleStatus(
*/
export function mapStatus(
statusCode: string,
submoduleStatusCode: string
submoduleStatusCode: string,
renameOrCopyScore: number | undefined
): FileEntry {
const submoduleStatus = mapSubmoduleStatus(submoduleStatusCode)
@ -268,6 +273,7 @@ export function mapStatus(
kind: 'renamed',
index: GitStatusEntry.Renamed,
workingTree: GitStatusEntry.Unchanged,
renameOrCopyScore,
submoduleStatus,
}
}
@ -277,6 +283,7 @@ export function mapStatus(
kind: 'renamed',
index: GitStatusEntry.Unchanged,
workingTree: GitStatusEntry.Renamed,
renameOrCopyScore,
submoduleStatus,
}
}
@ -324,6 +331,7 @@ export function mapStatus(
kind: 'renamed',
index: GitStatusEntry.Renamed,
workingTree: GitStatusEntry.Modified,
renameOrCopyScore,
submoduleStatus,
}
}
@ -333,6 +341,7 @@ export function mapStatus(
kind: 'renamed',
index: GitStatusEntry.Renamed,
workingTree: GitStatusEntry.Deleted,
renameOrCopyScore,
submoduleStatus,
}
}

View File

@ -47,6 +47,7 @@ export type PlainFileStatus = {
export type CopiedOrRenamedFileStatus = {
kind: AppFileStatusKind.Copied | AppFileStatusKind.Renamed
oldPath: string
renameIncludesModifications: boolean;
submoduleStatus?: SubmoduleStatus
}
@ -146,6 +147,8 @@ type RenamedOrCopiedEntry = {
readonly workingTree?: GitStatusEntry
/** the submodule status for this entry */
readonly submoduleStatus?: SubmoduleStatus
/** The rename or copy score in the case of a renamed file */
readonly renameOrCopyScore?: number
}
export enum UnmergedEntrySummary {

View File

@ -33,6 +33,8 @@ import { SideBySideDiff } from './side-by-side-diff'
import { enableExperimentalDiffViewer } from '../../lib/feature-flag'
import { IFileContents } from './syntax-highlighting'
import { SubmoduleDiff } from './submodule-diff'
import { Octicon } from '../octicons'
import * as OcticonSymbol from '../octicons/octicons.generated'
// image used when no diff is displayed
const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg')
@ -226,11 +228,24 @@ export class Diff extends React.Component<IDiffProps, IDiffState> {
}
if (this.props.file.status.kind === AppFileStatusKind.Renamed) {
return (
<div className="panel renamed">
The file was renamed but not changed
</div>
)
// Check if it was changed too
if (this.props.file.status.renameIncludesModifications)
{
return (
<div className="panel renamed">
<Octicon symbol={OcticonSymbol.alert} />
The file was renamed and includes changes.
</div>
)
}
else
{
return (
<div className="panel renamed">
The file was renamed but not changed
</div>
)
}
}
if (

BIN
docs/assets/ado-prompt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -1,5 +1,19 @@
# Authenticating to Azure DevOps with GitHub Desktop
GitHub Desktop now provides support for [Git Credential Manager (GCM)](https://gh.io/gcm), which makes the task of authenticating to Azure DevOps repositories easy and secure. This feature can be enabled by going to **File** > **Options** > **Advanced** on Windows, or **GitHub Desktop** > **Preferences** > **Advanced** on macOS, and then selecting the **Use Git Credential Manager** checkbox.
![screenshot of the GitHub Desktop settings menu with the "Use Git Credential Manager" checkbox outlined](/docs/assets/git-credential-manager.png)
When GCM is enabled all credentials for Azure DevOps will be handled, and stored, outside of GitHub Desktop. GCM supports browser authentication and will avoid the need to create personal access tokens (PATs).
Your browser will open to authenticate to your Azure DevOps account using GCM when you go to **File** > **Clone Repository** > **URL** and enter the HTTPS clone URL of the repository.
![screenshot of a browser window showing the option to pick a Microsoft account](/docs/assets/ado-prompt.png)
If you would prefer not to use GCM and need to create a personal access token in Azure DevOps you can follow the steps below.
## Creating a Personal Access Token in Azure DevOps
To authenticate against Azure DevOps repositories you will need to create a personal access token.

View File

@ -1,5 +1,17 @@
# Authenticating to Bitbucket with GitHub Desktop
GitHub Desktop now provides support for [Git Credential Manager (GCM)](https://gh.io/gcm), which makes the task of authenticating to Bitbucket repositories easy and secure. This feature can be enabled by going to **File** > **Options** > **Advanced** on Windows, or **GitHub Desktop** > **Preferences** > **Advanced** on macOS, and then selecting the **Use Git Credential Manager** checkbox.
![screenshot of the GitHub Desktop settings menu with the "Use Git Credential Manager" checkbox outlined](/docs/assets/git-credential-manager.png)
When Git Credential Manager is enabled all credentials for Bitbucket will be handled, and stored, outside of GitHub Desktop. Git Credential Manager supports browser authentication and will avoid the need to create personal access tokens (PATs).
The prompt to authenticate to your Bitbucket account using GCM will be shown when you go to **File** > **Clone Repository** > **URL** and enter the HTTPS clone URL of the repository.
![screenshot of a prompt showing the option to sign in with your browser to an Atlassian account](/docs/assets/bitbucket-prompt.png)
If you would prefer not to use GCM and need to create a personal access token in Bitbucket you can follow the steps below.
## Creating a Personal Access Token in Bitbucket
To authenticate against Bitbucket repositories you will need to create a personal access token.

View File

@ -1,5 +1,17 @@
# Authenticating to GitLab with GitHub Desktop
GitHub Desktop now provides support for [Git Credential Manager (GCM)](https://gh.io/gcm), which makes the task of authenticating to GitLab repositories easy and secure. This feature can be enabled by going to **File** > **Options** > **Advanced** on Windows, or **GitHub Desktop** > **Preferences** > **Advanced** on macOS, and then selecting the **Use Git Credential Manager** checkbox.
![screenshot of the GitHub Desktop settings menu with the "Use Git Credential Manager" checkbox outlined](/docs/assets/git-credential-manager.png)
When GCM is enabled all credentials for GitLab will be handled, and stored, outside of GitHub Desktop. GCM supports browser authentication and will avoid the need to create personal access tokens (PATs).
The prompt to authenticate to your GitLab account using GCM will be shown after you enter the HTTPS clone URL of the GitLab repository by going to **File** > **Clone Repository** > **URL**.
![screenshot of a prompt showing the option to sign in with your browser to a GitLab account](/docs/assets/gitlab-prompt.png)
If you would prefer not to use GCM and need to create a personal access token in GitLab you can follow the steps below.
## Creating a Personal Access Token in GitLab
To authenticate against GitLab repositories you will need to create a personal access token.