Skip to content

Commit

Permalink
Fix for pushing to empty repo on Mononoke Git server
Browse files Browse the repository at this point in the history
Summary:
In Protocol V1, the capability of the server is advertised along with the ref advertisement. This is done by null-separating the capabilities from the first ref while the rest of the refs are sent normally.

However, since the capabilities are tied to ref advertisement in the write path, having no refs mean that we won't send any capabilities to the client. This is what was wrong with the current implementation. Now the logic has been corrected to make it consistent with [the spec](https://git-scm.com/docs/pack-protocol#_reference_discovery)

Reviewed By: andreacampi

Differential Revision: D67978800

fbshipit-source-id: bb9ea76dca8f27ac3ed1f4b6b06fc55f795e4804
  • Loading branch information
RajivTS authored and facebook-github-bot committed Jan 10, 2025
1 parent 4a71278 commit 04ed1b6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
31 changes: 24 additions & 7 deletions eden/mononoke/git_server/src/read/capability_advertisement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use core::str;

use anyhow::Error;
use bytes::Bytes;
use gix_hash::Kind;
use gix_hash::ObjectId;
use gotham::mime;
use gotham::state::FromState;
use gotham::state::State;
Expand Down Expand Up @@ -84,14 +86,29 @@ async fn write_advertisement(
.into_iter()
.collect();
refs.sort_by(|a, b| a.0.cmp(&b.0));

let mut refs = refs.into_iter();
if let Some((ref_name, target)) = refs.next() {
let first_ref_line = ref_line(ref_name.as_str(), &target);
write_text_packetline(
format!("{}\0{}", first_ref_line, RECEIVE_PACK_CAPABILITIES).as_bytes(),
output,
)
.await?;
match refs.next() {
Some((ref_name, target)) => {
let first_ref_line = ref_line(ref_name.as_str(), &target);
write_text_packetline(
format!("{}\0{}", first_ref_line, RECEIVE_PACK_CAPABILITIES).as_bytes(),
output,
)
.await?;
}
None => {
write_text_packetline(
format!(
"{} capabilities^{{}}\0{}",
ObjectId::null(Kind::Sha1),
RECEIVE_PACK_CAPABILITIES
)
.as_bytes(),
output,
)
.await?;
}
}
for (ref_name, target) in refs {
write_text_packetline(ref_line(ref_name.as_str(), &target).as_bytes(), output).await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@

# Push Git repository to Mononoke
$ git_client push origin --all
error: failed to push some refs to 'https://*/repos/git/ro/repo.git' (glob)
[1]
To https://*/repos/git/ro/repo.git (glob)
* [new branch] master_bookmark -> master_bookmark

0 comments on commit 04ed1b6

Please sign in to comment.