Skip to content

Commit 81d859a

Browse files
committed
change of plan
1 parent 66f629b commit 81d859a

File tree

6 files changed

+67
-72
lines changed

6 files changed

+67
-72
lines changed

src/subcommand/push_subcommand.cpp

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "../subcommand/push_subcommand.hpp"
22

3+
#include <algorithm>
34
#include <iostream>
45
#include <optional>
5-
#include <unordered_map>
6+
#include <string>
67
#include <string_view>
78

89
#include <git2.h>
@@ -17,7 +18,6 @@ push_subcommand::push_subcommand(const libgit2_object&, CLI::App& app)
1718
auto* sub = app.add_subcommand("push", "Update remote refs along with associated objects");
1819

1920
sub->add_option("<remote>", m_remote_name, "The remote to push to")->default_val("origin");
20-
sub->add_option("<branch>", m_branch_name, "The branch to push");
2121
sub->add_option("<refspec>", m_refspecs, "The refspec(s) to push");
2222
sub->add_flag(
2323
"--all,--branches",
@@ -71,22 +71,15 @@ void push_subcommand::run()
7171
else if (m_refspecs.empty())
7272
{
7373
std::string branch;
74-
if (!m_branch_name.empty())
74+
try
7575
{
76-
branch = m_branch_name;
76+
auto head_ref = repo.head();
77+
branch = head_ref.short_name();
7778
}
78-
else
79+
catch (...)
7980
{
80-
try
81-
{
82-
auto head_ref = repo.head();
83-
branch = head_ref.short_name();
84-
}
85-
catch (...)
86-
{
87-
std::cerr << "Could not determine current branch to push." << std::endl;
88-
return;
89-
}
81+
std::cerr << "Could not determine current branch to push." << std::endl;
82+
return;
9083
}
9184
std::string refspec = "refs/heads/" + branch;
9285
m_refspecs.push_back(refspec);
@@ -95,20 +88,34 @@ void push_subcommand::run()
9588
git_strarray* refspecs_ptr = nullptr;
9689
refspecs_ptr = refspecs_wrapper;
9790

98-
// Take a snapshot of remote branches to check which ones are new after push
99-
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
100-
callbacks.credentials = user_credentials;
101-
credentials_payload creds_payload;
102-
callbacks.payload = &creds_payload;
103-
push_opts.callbacks.payload = &creds_payload;
104-
105-
auto remote_heads = remote.list_heads(&callbacks);
91+
// // Take a snapshot of remote branches to check which ones are new after push
92+
// git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
93+
// callbacks.credentials = user_credentials;
94+
// credentials_payload creds_payload;
95+
// callbacks.payload = &creds_payload;
96+
// push_opts.callbacks.payload = &creds_payload;
10697

98+
// auto remote_heads = remote.list_heads(&callbacks);
99+
//
100+
//
107101
// Map with names of branches and their oids before push
108-
std::unordered_map<std::string, git_oid> remote_heads_map;
109-
for (const auto& h : remote_heads)
102+
// std::unordered_map<std::string, git_oid> remote_heads_map;
103+
// for (const auto& h : remote_heads)
104+
// {
105+
// remote_heads_map.emplace(h.name, h.oid);
106+
// }
107+
108+
// Take a snapshot of repo's references to check which ones are new after push
109+
auto repo_refs = repo.reference_list();
110+
std::vector<std::string> repo_refs_remote;
111+
for (int i = 0; i < repo_refs.size(); ++i)
110112
{
111-
remote_heads_map.emplace(h.name, h.oid);
113+
std::string prefix_remote = "refs/remote/";
114+
if (repo_refs[i].substr(0, prefix_remote.size()) == prefix_remote)
115+
{
116+
std::string remote_short_name = repo_refs[i].substr(prefix_remote.size());
117+
repo_refs_remote.push_back(remote_short_name);
118+
}
112119
}
113120

114121
remote.push(refspecs_ptr, &push_opts);
@@ -117,11 +124,11 @@ void push_subcommand::run()
117124
for (const auto& refspec : m_refspecs)
118125
{
119126
std::string_view ref_view(refspec);
120-
std::string_view prefix = "refs/heads/";
127+
std::string_view prefix_local = "refs/heads/";
121128
std::string local_short_name;
122-
if (ref_view.substr(0, prefix.size()) == prefix)
129+
if (ref_view.substr(0, prefix_local.size()) == prefix_local)
123130
{
124-
local_short_name = ref_view.substr(prefix.size());
131+
local_short_name = ref_view.substr(prefix_local.size());
125132
}
126133
else
127134
{
@@ -148,14 +155,14 @@ void push_subcommand::run()
148155
}
149156
}
150157

151-
auto iter = remote_heads_map.find(remote_ref);
152-
if (iter == remote_heads_map.end())
158+
auto iter = std::find(repo_refs_remote.begin(), repo_refs_remote.end(), remote_ref);
159+
if (iter == repo_refs_remote.end())
153160
{
154161
std::cout << " * [new branch] " << local_short_name << " -> " << remote_branch << std::endl;
155162
continue;
156163
}
157164

158-
git_oid remote_oid = iter->second;
165+
git_oid remote_oid = repo.ref_name_to_id(*iter);
159166

160167
std::optional<git_oid> local_oid_opt;
161168
if (auto ref_opt = repo.find_reference_dwim(("refs/heads/" + local_short_name)))

src/subcommand/push_subcommand.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class push_subcommand
1717
private:
1818

1919
std::string m_remote_name;
20-
std::string m_branch_name;
2120
std::vector<std::string> m_refspecs;
2221
bool m_branches_flag = false;
2322
};

src/utils/credentials.cpp

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,53 +15,25 @@ int user_credentials(
1515
void* payload
1616
)
1717
{
18-
credentials_payload* cached = payload ? static_cast<credentials_payload*>(payload) : nullptr;
19-
2018
// Check for cached credentials here, if desired.
2119
// It might be necessary to make this function stateful to avoid repeating unnecessary checks.
2220

2321
*out = nullptr;
2422

2523
if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT)
2624
{
27-
std::string username;
28-
if (username_from_url && username_from_url[0] != '\0')
29-
{
30-
username = username_from_url;
31-
}
32-
else if (cached && cached->username.has_value())
33-
{
34-
username = *cached->username;
35-
}
36-
else
25+
std::string username = username_from_url ? username_from_url : "";
26+
if (username.empty())
3727
{
3828
username = prompt_input("Username: ");
39-
if (cached && !username.empty())
40-
{
41-
cached->username = username;
42-
}
4329
}
44-
4530
if (username.empty())
4631
{
4732
giterr_set_str(GIT_ERROR_HTTP, "No username specified");
4833
return GIT_EAUTH;
4934
}
5035

5136
std::string password = prompt_input("Password: ", false);
52-
if (cached && cached->password.has_value())
53-
{
54-
password = *cached->password;
55-
}
56-
else
57-
{
58-
password = prompt_input("Password: ", false);
59-
if (cached && !password.empty())
60-
{
61-
cached->password = password;
62-
}
63-
}
64-
6537
if (password.empty())
6638
{
6739
giterr_set_str(GIT_ERROR_HTTP, "No password specified");

src/utils/credentials.hpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
#pragma once
22

3-
#include <optional>
4-
#include <string>
5-
63
#include <git2/credential.h>
74

8-
struct credentials_payload
9-
{
10-
std::optional<std::string> username;
11-
std::optional<std::string> password;
12-
};
13-
145
// Libgit2 callback of type git_credential_acquire_cb to obtain user credentials
156
// (username and password) to authenticate remote https access.
167
int user_credentials(

src/wrapper/repository_wrapper.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
#include <optional>
77
#include <string_view>
88
#include <git2/buffer.h>
9+
#include <git2/oid.h>
10+
#include <git2/refs.h>
11+
#include <git2/strarray.h>
12+
#include <git2/types.h>
913

1014
#include "../utils/git_exception.hpp"
1115
#include "../wrapper/commit_wrapper.hpp"
@@ -137,6 +141,26 @@ std::optional<reference_wrapper> repository_wrapper::find_reference_dwim(std::st
137141
return rc == 0 ? std::make_optional(reference_wrapper(ref)) : std::nullopt;
138142
}
139143

144+
std::vector<std::string> repository_wrapper::reference_list() const
145+
{
146+
git_strarray* array;
147+
throw_if_error(git_reference_list(array, *this));
148+
std::vector<std::string> result;
149+
for (size_t i = 0; i < array->count; ++i)
150+
{
151+
result.push_back(array->strings[i]);
152+
}
153+
git_strarray_free(array);
154+
return result;
155+
}
156+
157+
const git_oid& repository_wrapper::ref_name_to_id(std::string ref_name) const
158+
{
159+
git_oid* ref_id;
160+
throw_if_error(git_reference_name_to_id(ref_id, *this, ref_name.c_str()));
161+
return *ref_id;
162+
}
163+
140164
// Index
141165

142166
index_wrapper repository_wrapper::make_index()

src/wrapper/repository_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class repository_wrapper : public wrapper_base<git_repository>
6262
// References
6363
reference_wrapper find_reference(std::string_view ref_name) const;
6464
std::optional<reference_wrapper> find_reference_dwim(std::string_view ref_name) const;
65+
std::vector<std::string> reference_list() const;
66+
const git_oid& ref_name_to_id(std::string ref_name) const;
6567

6668
// Index
6769
index_wrapper make_index();

0 commit comments

Comments
 (0)