1use anyhow::*;
2use std::io::Write;
3use std::result::Result::Ok;
4
5use crate::repo;
6
7pub fn test_auth<W: Write>(repo: &repo::Repo, stdout: &mut W) -> Result<()> {
8 writeln!(stdout, "Testing authentication for repository...")?;
9 writeln!(stdout, "Repository: {}", repo.work_dir.display())?;
10 writeln!(stdout)?;
11
12 let head_ref = repo.git_repo.head()?;
14 let branch_name = head_ref
15 .shorthand()
16 .ok_or_else(|| anyhow!("Cannot get branch name"))?;
17
18 writeln!(stdout, "Current branch: {}", branch_name)?;
19
20 if let Some(tracking) = repo.tracking_branch(branch_name)? {
22 writeln!(stdout, "Remote: {}", tracking.remote)?;
23 writeln!(stdout, "Remote ref: {}", tracking.remote_ref)?;
24 writeln!(stdout)?;
25
26 match repo.git_repo.find_remote(&tracking.remote) {
28 Ok(mut remote) => {
29 writeln!(stdout, "Attempting to connect to remote...")?;
30 writeln!(stdout)?;
31
32 match remote.connect_auth(
34 git2::Direction::Fetch,
35 Some(repo.remote_callbacks_verbose()?),
36 None,
37 ) {
38 Ok(connection) => {
39 writeln!(stdout)?;
40 writeln!(stdout, "? Connection successful!")?;
41 writeln!(stdout)?;
42 writeln!(stdout, "Available remote heads:")?;
43 for head in connection.list()?.iter() {
44 writeln!(stdout, " - {}", head.name())?;
45 }
46 drop(connection);
47 },
48 Err(e) => {
49 writeln!(stdout)?;
50 writeln!(stdout, "? Connection failed: {}", e)?;
51 writeln!(stdout)?;
52 writeln!(stdout, "Troubleshooting steps:")?;
53 writeln!(stdout, "1. Check SSH agent is running: ssh-add -l")?;
54 writeln!(
55 stdout,
56 "2. Verify SSH_AUTH_SOCK is set: echo $SSH_AUTH_SOCK"
57 )?;
58 writeln!(
59 stdout,
60 "3. Test SSH connection: ssh -T git@<hostname>"
61 )?;
62 writeln!(stdout, "4. Check SSH keys exist: ls -la ~/.ssh/")?;
63 return Err(e.into());
64 },
65 }
66 },
67 Err(e) => {
68 writeln!(stdout, "? Remote '{}' not found: {}", tracking.remote, e)?;
69 return Err(e.into());
70 },
71 }
72 } else {
73 writeln!(
74 stdout,
75 "No tracking branch configured for '{}'",
76 branch_name
77 )?;
78 writeln!(stdout)?;
79 writeln!(stdout, "To set up tracking, run:")?;
80 writeln!(
81 stdout,
82 " git branch --set-upstream-to=<remote>/<branch> {}",
83 branch_name
84 )?;
85 }
86
87 Ok(())
88}