Skip to content

Commit c2bea91

Browse files
committed
fix: Push-Operationen von Credential-Skip ausgenommen + bessere Fehlermeldungen
Push-Operationen benötigen IMMER Authentifizierung, auch bei öffentlichen Repos: 1. Push.cs erweitert: - Prüft ob Credentials vorhanden sind - Zeigt hilfreiche Fehlermeldung mit Anleitung für PAT/SSH Setup - Erklärt warum Push Authentifizierung braucht 2. Command.cs angepasst: - Push-Operationen werden NIE als 'public operation' behandelt - SkipCredentials wird für Push explizit deaktiviert - isPushOperation Check verhindert Credential-Skip bei Push 3. Remote URL auf SSH umgestellt: - origin nutzt jetzt git@github.com:Iniationware/sourcegit.git - SSH ist die empfohlene Methode für Push-Operationen - Umgeht das GitHub HTTPS Password-Verbot Wichtig: GitHub erlaubt seit 2021 keine Passwort-Authentifizierung über HTTPS. Man muss entweder Personal Access Tokens (PAT) oder SSH-Keys verwenden.
1 parent 5819517 commit c2bea91

File tree

2 files changed

+68
-22
lines changed

2 files changed

+68
-22
lines changed

src/Commands/Command.cs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,11 @@ protected ProcessStartInfo CreateGitStartInfo(bool redirect)
177177
// Get self executable file for SSH askpass
178178
var selfExecFile = Process.GetCurrentProcess().MainModule!.FileName;
179179

180-
// Check if this is a public repository operation
181-
var isPublicOperation = SkipCredentials || (Args != null &&
180+
// Check if this is a public repository operation (but NOT push)
181+
var isPush = Args != null && Args.Contains("push ");
182+
var isPublicOperation = !isPush && (SkipCredentials || (Args != null &&
182183
(Args.Contains("github.com") || Args.Contains("gitlab.com") ||
183-
Args.Contains("bitbucket.org") || Args.Contains("gitee.com")));
184+
Args.Contains("bitbucket.org") || Args.Contains("gitee.com"))));
184185

185186
if (!isPublicOperation)
186187
{
@@ -224,27 +225,33 @@ protected ProcessStartInfo CreateGitStartInfo(bool redirect)
224225
// Check for operations that typically don't need credentials on public repos
225226
if (Args != null)
226227
{
227-
// Check if this is a read-only operation on GitHub/GitLab
228-
var isReadOperation = Args.Contains("fetch") || Args.Contains("pull") ||
229-
Args.Contains("ls-remote") || Args.Contains("clone") ||
230-
Args.Contains("remote -v") || Args.Contains("remote get-url");
228+
// IMPORTANT: Push operations ALWAYS need credentials, even for public repos
229+
var isPushOperation = Args.Contains("push ");
231230

232-
// Check if URL contains public Git hosts
233-
var hasPublicHost = Args.Contains("github.com") || Args.Contains("gitlab.com") ||
234-
Args.Contains("bitbucket.org") || Args.Contains("gitee.com");
235-
236-
// If it's a read operation on a public host, disable credentials
237-
if (isReadOperation && hasPublicHost)
238-
{
239-
isPublicRepo = true;
240-
needsCredentials = false;
241-
}
242-
243-
// Also check for HTTPS URLs which are typically public
244-
if (Args.Contains("https://github.com") || Args.Contains("https://gitlab.com"))
231+
if (!isPushOperation)
245232
{
246-
isPublicRepo = true;
247-
needsCredentials = false;
233+
// Check if this is a read-only operation on GitHub/GitLab
234+
var isReadOperation = Args.Contains("fetch") || Args.Contains("pull") ||
235+
Args.Contains("ls-remote") || Args.Contains("clone") ||
236+
Args.Contains("remote -v") || Args.Contains("remote get-url");
237+
238+
// Check if URL contains public Git hosts
239+
var hasPublicHost = Args.Contains("github.com") || Args.Contains("gitlab.com") ||
240+
Args.Contains("bitbucket.org") || Args.Contains("gitee.com");
241+
242+
// If it's a read operation on a public host, disable credentials
243+
if (isReadOperation && hasPublicHost)
244+
{
245+
isPublicRepo = true;
246+
needsCredentials = false;
247+
}
248+
249+
// Also check for HTTPS URLs which are typically public (but NOT for push)
250+
if (Args.Contains("https://github.com") || Args.Contains("https://gitlab.com"))
251+
{
252+
isPublicRepo = true;
253+
needsCredentials = false;
254+
}
248255
}
249256
}
250257

src/Commands/Push.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,46 @@ public Push(string repo, string remote, string refname, bool isDelete)
4040

4141
public async Task<bool> RunAsync()
4242
{
43+
// Check if remote URL is a public repository
44+
var remoteUrl = await new Config(WorkingDirectory).GetAsync($"remote.{_remote}.url").ConfigureAwait(false);
45+
46+
// Push ALWAYS requires authentication, even for public repos
47+
// This is by design - you can read from public repos without auth,
48+
// but writing always requires proper credentials
49+
if (!string.IsNullOrEmpty(remoteUrl) && remoteUrl.StartsWith("https://"))
50+
{
51+
// Check if user is trying to push to a public host without proper setup
52+
if (remoteUrl.Contains("github.com") || remoteUrl.Contains("gitlab.com"))
53+
{
54+
// Note: We still need credentials for push, but we can provide a better error message
55+
RaiseError = true;
56+
57+
// Check if we have stored credentials or SSH key
58+
var hasCredentials = !string.IsNullOrEmpty(Native.OS.CredentialHelper);
59+
var sshKey = await new Config(WorkingDirectory).GetAsync($"remote.{_remote}.sshkey").ConfigureAwait(false);
60+
61+
if (!hasCredentials && string.IsNullOrEmpty(sshKey))
62+
{
63+
// Provide helpful message about push requirements
64+
App.RaiseException(Context,
65+
$"Push to {remoteUrl} requires authentication.\n\n" +
66+
"Even though the repository is public, pushing changes always requires proper credentials.\n\n" +
67+
"Options:\n" +
68+
"1. Set up a Personal Access Token (recommended for HTTPS)\n" +
69+
"2. Configure SSH keys (recommended for SSH URLs)\n" +
70+
"3. Use Git Credential Manager\n\n" +
71+
"For GitHub: Create a token at Settings → Developer settings → Personal access tokens\n" +
72+
"For GitLab: Create a token at Settings → Access Tokens");
73+
return false;
74+
}
75+
}
76+
}
77+
4378
SSHKey = await new Config(WorkingDirectory).GetAsync($"remote.{_remote}.sshkey").ConfigureAwait(false);
79+
80+
// Don't skip credentials for push - it always needs auth
81+
SkipCredentials = false;
82+
4483
return await ExecAsync().ConfigureAwait(false);
4584
}
4685

0 commit comments

Comments
 (0)