diff --git a/assets/gitcomet-512.png b/assets/gitcomet-512.png
new file mode 100644
index 0000000..d20a7fe
Binary files /dev/null and b/assets/gitcomet-512.png differ
diff --git a/assets/gitcomet-512.svg b/assets/gitcomet-512.svg
new file mode 100644
index 0000000..6e813b5
--- /dev/null
+++ b/assets/gitcomet-512.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/gitcomet_logo_window.png b/assets/gitcomet_logo_window.png
new file mode 100644
index 0000000..c4378dc
Binary files /dev/null and b/assets/gitcomet_logo_window.png differ
diff --git a/assets/gitcomet_logo_window.svg b/assets/gitcomet_logo_window.svg
new file mode 100644
index 0000000..1c36840
--- /dev/null
+++ b/assets/gitcomet_logo_window.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/gitgpui_logo.png b/assets/gitgpui_logo.png
deleted file mode 100644
index 46756af..0000000
Binary files a/assets/gitgpui_logo.png and /dev/null differ
diff --git a/assets/gitgpui_logo.svg b/assets/gitgpui_logo.svg
deleted file mode 100644
index 538efd2..0000000
--- a/assets/gitgpui_logo.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
diff --git a/assets/gitgpui_logo_window.svg b/assets/gitgpui_logo_window.svg
deleted file mode 100644
index 822cc04..0000000
--- a/assets/gitgpui_logo_window.svg
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
diff --git a/assets/linux/hicolor/scalable/apps/gitcomet-512.svg b/assets/linux/hicolor/scalable/apps/gitcomet-512.svg
new file mode 100644
index 0000000..6e813b5
--- /dev/null
+++ b/assets/linux/hicolor/scalable/apps/gitcomet-512.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/linux/hicolor/scalable/apps/gitgpui.svg b/assets/linux/hicolor/scalable/apps/gitgpui.svg
deleted file mode 100644
index 538efd2..0000000
--- a/assets/linux/hicolor/scalable/apps/gitgpui.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
diff --git a/crates/gitgpui-git-gix/src/repo/blame.rs b/crates/gitgpui-git-gix/src/repo/blame.rs
index 74ee01e..a3210cb 100644
--- a/crates/gitgpui-git-gix/src/repo/blame.rs
+++ b/crates/gitgpui-git-gix/src/repo/blame.rs
@@ -255,3 +255,75 @@ fn parse_git_blame_porcelain(output: &str) -> Vec {
out
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::collections::BTreeSet;
+
+ const GITPY_BLAME: &str = include_str!("../../tests/fixtures/gitpython/blame");
+ const GITPY_BLAME_COMPLEX_REVISION: &str =
+ include_str!("../../tests/fixtures/gitpython/blame_complex_revision");
+ const GITPY_BLAME_BINARY: &[u8] = include_bytes!("../../tests/fixtures/gitpython/blame_binary");
+
+ #[test]
+ fn parse_git_blame_porcelain_handles_gitpython_blame_fixture() {
+ let parsed = parse_git_blame_porcelain(GITPY_BLAME);
+ assert_eq!(parsed.len(), 25);
+
+ let first = parsed
+ .first()
+ .expect("fixture should parse at least one line");
+ assert_eq!(first.commit_id, "634396b2f541a9f2d58b00be1a07f0c358b999b3");
+ assert_eq!(first.author, "Tom Preston-Werner");
+ assert_eq!(first.author_time_unix, Some(1_191_997_100));
+ assert_eq!(first.summary, "initial grit setup");
+ assert_eq!(
+ first.line,
+ "$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed"
+ );
+
+ let second = parsed.get(1).expect("fixture should parse second line");
+ assert_eq!(second.commit_id, first.commit_id);
+ assert_eq!(second.author, first.author);
+ assert_eq!(second.author_time_unix, first.author_time_unix);
+ assert_eq!(second.summary, first.summary);
+ assert!(second.line.is_empty());
+ }
+
+ #[test]
+ fn parse_git_blame_porcelain_handles_gitpython_complex_revision_fixture() {
+ let parsed = parse_git_blame_porcelain(GITPY_BLAME_COMPLEX_REVISION);
+ assert_eq!(parsed.len(), 83);
+
+ let unique_commits = parsed
+ .iter()
+ .map(|line| line.commit_id.as_str())
+ .collect::>();
+ assert_eq!(unique_commits.len(), 1);
+
+ let first = parsed.first().expect("complex fixture should parse");
+ assert_eq!(first.commit_id, "e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e");
+ assert_eq!(first.author, "Sebastian Thiel");
+ assert_eq!(first.summary, "Fixed PY3 support.");
+ assert_eq!(first.line, "## GitPython");
+ }
+
+ #[test]
+ fn parse_git_blame_porcelain_handles_gitpython_binary_fixture() {
+ let raw = String::from_utf8_lossy(GITPY_BLAME_BINARY);
+ let parsed = parse_git_blame_porcelain(&raw);
+ assert_eq!(parsed.len(), 9);
+
+ let unique_commits = parsed
+ .iter()
+ .map(|line| line.commit_id.as_str())
+ .collect::>();
+ assert_eq!(unique_commits.len(), 2);
+
+ let first = parsed.first().expect("binary fixture should parse");
+ assert_eq!(first.author, "Sebastian Thiel");
+ assert_eq!(first.summary, "binary");
+ assert!(parsed.iter().any(|line| line.line.contains("hi")));
+ }
+}
diff --git a/crates/gitgpui-git-gix/src/util.rs b/crates/gitgpui-git-gix/src/util.rs
index dba6fc7..2af476e 100644
--- a/crates/gitgpui-git-gix/src/util.rs
+++ b/crates/gitgpui-git-gix/src/util.rs
@@ -179,7 +179,7 @@ pub(crate) fn parse_git_log_pretty_records(output: &str) -> LogPage {
}
pub(crate) fn parse_name_status_line(line: &str) -> Option {
- let line = line.trim();
+ let line = line.trim_end_matches(&['\n', '\r'][..]);
if line.is_empty() {
return None;
}
@@ -206,7 +206,6 @@ pub(crate) fn parse_name_status_line(line: &str) -> Option {
}
_ => parts.next().unwrap_or_default(),
};
- let path = path.trim();
if path.is_empty() {
return None;
}
@@ -275,6 +274,133 @@ pub(crate) fn parse_remote_branches(output: &str) -> Vec {
mod tests {
use super::*;
+ const GITPY_FOR_EACH_REF_WITH_PATH_COMPONENT: &[u8] =
+ include_bytes!("../tests/fixtures/gitpython/for_each_ref_with_path_component");
+ const GITPY_DIFF_FILE_WITH_COLON: &[u8] =
+ include_bytes!("../tests/fixtures/gitpython/diff_file_with_colon");
+ const GITPY_DIFF_FILE_WITH_SPACES: &str =
+ include_str!("../tests/fixtures/gitpython/diff_file_with_spaces");
+ const GITPY_DIFF_RENAME: &str = include_str!("../tests/fixtures/gitpython/diff_rename");
+ const GITPY_DIFF_CHANGE_IN_TYPE_RAW: &str =
+ include_str!("../tests/fixtures/gitpython/diff_change_in_type_raw");
+ const GITPY_DIFF_COPIED_MODE_RAW: &str =
+ include_str!("../tests/fixtures/gitpython/diff_copied_mode_raw");
+ const GITPY_DIFF_RENAME_RAW: &str = include_str!("../tests/fixtures/gitpython/diff_rename_raw");
+ const GITPY_DIFF_RAW_BINARY: &str = include_str!("../tests/fixtures/gitpython/diff_raw_binary");
+ const GITPY_DIFF_INDEX_RAW: &str = include_str!("../tests/fixtures/gitpython/diff_index_raw");
+ const GITPY_DIFF_PATCH_UNSAFE_PATHS: &[u8] =
+ include_bytes!("../tests/fixtures/gitpython/diff_patch_unsafe_paths");
+ const GITPY_UNCOMMON_BRANCH_PREFIX_FETCH_HEAD: &str =
+ include_str!("../tests/fixtures/gitpython/uncommon_branch_prefix_FETCH_HEAD");
+ const GITPY_REV_LIST_SINGLE: &str = include_str!("../tests/fixtures/gitpython/rev_list_single");
+ const GITPY_REV_LIST_COMMIT_STATS: &str =
+ include_str!("../tests/fixtures/gitpython/rev_list_commit_stats");
+
+ fn gitpython_raw_to_name_status_line(raw: &str) -> String {
+ let mut parts = raw.split_whitespace();
+ let _old_mode = parts.next().expect("raw fixture old mode");
+ let _new_mode = parts.next().expect("raw fixture new mode");
+ let _old_sha = parts.next().expect("raw fixture old sha");
+ let _new_sha = parts.next().expect("raw fixture new sha");
+ let status = parts.next().expect("raw fixture status");
+ let first_path = parts.next().expect("raw fixture path");
+
+ if status.starts_with('R') || status.starts_with('C') {
+ let second_path = parts.next().expect("raw fixture second path");
+ format!("{status}\t{first_path}\t{second_path}")
+ } else {
+ format!("{status}\t{first_path}")
+ }
+ }
+
+ fn gitpython_patch_b_paths(patch_bytes: &[u8]) -> Vec {
+ let text = String::from_utf8_lossy(patch_bytes);
+ let mut out = Vec::new();
+ for line in text.lines() {
+ let Some(rest) = line.strip_prefix("+++ ") else {
+ continue;
+ };
+ if rest == "/dev/null" {
+ continue;
+ }
+ if let Some(path) = rest.strip_prefix("b/") {
+ out.push(path.to_string());
+ } else if let Some(quoted) = rest.strip_prefix("\"b/") {
+ let path = quoted
+ .strip_suffix('\"')
+ .expect("quoted +++ line should have trailing quote");
+ out.push(path.to_string());
+ }
+ }
+ out
+ }
+
+ fn gitpython_fetch_head_to_remote_ref_output(fetch_head: &str, remote: &str) -> String {
+ let mut out = String::new();
+ for line in fetch_head.lines() {
+ let Some((sha, rest)) = line.split_once('\t') else {
+ continue;
+ };
+ let sha = sha.trim();
+ if sha.is_empty() {
+ continue;
+ }
+ let Some(start) = rest.find("'refs/") else {
+ continue;
+ };
+ let refs_and_after = &rest[start + 1..];
+ let Some((full_ref, _)) = refs_and_after.split_once('\'') else {
+ continue;
+ };
+ let short_ref = full_ref.strip_prefix("refs/").unwrap_or(full_ref);
+ out.push_str(remote);
+ out.push('/');
+ out.push_str(short_ref);
+ out.push('\t');
+ out.push_str(sha);
+ out.push('\n');
+ }
+ out
+ }
+
+ fn gitpython_rev_list_fixture_to_pretty_record(fixture: &str) -> String {
+ let id = fixture
+ .lines()
+ .find_map(|line| line.strip_prefix("commit "))
+ .expect("rev-list fixture should contain commit id")
+ .trim();
+
+ let parents = fixture
+ .lines()
+ .filter_map(|line| line.strip_prefix("parent "))
+ .map(str::trim)
+ .collect::>()
+ .join(" ");
+
+ let author_line = fixture
+ .lines()
+ .find(|line| line.starts_with("author "))
+ .expect("rev-list fixture should contain author line");
+ let author = author_line
+ .strip_prefix("author ")
+ .and_then(|line| line.split_once(" <").map(|(name, _)| name))
+ .expect("author line should include actor and email");
+ let time = author_line
+ .split_whitespace()
+ .rev()
+ .nth(1)
+ .expect("author line should contain unix timestamp")
+ .trim();
+
+ let summary = fixture
+ .lines()
+ .find_map(|line| line.strip_prefix(" "))
+ .unwrap_or_default()
+ .trim();
+
+ format!("{id}\x1f{parents}\x1f{author}\x1f{time}\x1f{summary}\x1e")
+ }
+
#[test]
fn parse_remote_branches_splits_and_skips_head() {
let output =
@@ -308,4 +434,222 @@ mod tests {
SystemTime::UNIX_EPOCH + Duration::from_secs(1)
);
}
+
+ #[test]
+ fn parse_remote_branches_handles_path_components_from_gitpython_fixture() {
+ let raw = std::str::from_utf8(GITPY_FOR_EACH_REF_WITH_PATH_COMPONENT)
+ .expect("fixture should be valid UTF-8");
+ let mut fields = raw.trim().split('\0');
+ let full_ref = fields.next().expect("refname field");
+ let oid = fields.next().expect("object id field");
+ let short = full_ref
+ .strip_prefix("refs/heads/")
+ .expect("heads ref prefix in fixture");
+
+ let output = format!("origin/{short}\t{oid}\norigin/HEAD\tdeadbeef\n");
+ let branches = parse_remote_branches(&output);
+
+ assert_eq!(branches.len(), 1);
+ assert_eq!(branches[0].remote, "origin");
+ assert_eq!(branches[0].name, "refactoring/feature1");
+ assert_eq!(branches[0].target, CommitId(oid.to_string()));
+ }
+
+ #[test]
+ fn parse_git_log_pretty_records_parses_single_commit_from_gitpython_fixture() {
+ let output = gitpython_rev_list_fixture_to_pretty_record(GITPY_REV_LIST_SINGLE);
+ let page = parse_git_log_pretty_records(&output);
+
+ assert_eq!(page.commits.len(), 1);
+ assert!(page.next_cursor.is_none());
+ let commit = &page.commits[0];
+ assert_eq!(
+ commit.id,
+ CommitId("4c8124ffcf4039d292442eeccabdeca5af5c5017".to_string())
+ );
+ assert_eq!(
+ commit.parent_ids,
+ vec![CommitId(
+ "634396b2f541a9f2d58b00be1a07f0c358b999b3".to_string()
+ )]
+ );
+ assert_eq!(commit.author, "Tom Preston-Werner");
+ assert_eq!(commit.summary, "implement Grit#heads");
+ assert_eq!(
+ commit.time,
+ SystemTime::UNIX_EPOCH + Duration::from_secs(1_191_999_972)
+ );
+ }
+
+ #[test]
+ fn parse_git_log_pretty_records_parses_multiple_gitpython_fixtures() {
+ let output = format!(
+ "{}{}",
+ gitpython_rev_list_fixture_to_pretty_record(GITPY_REV_LIST_SINGLE),
+ gitpython_rev_list_fixture_to_pretty_record(GITPY_REV_LIST_COMMIT_STATS)
+ );
+ let page = parse_git_log_pretty_records(&output);
+
+ assert_eq!(page.commits.len(), 2);
+ assert!(page.next_cursor.is_none());
+
+ assert_eq!(
+ page.commits[1].id,
+ CommitId("634396b2f541a9f2d58b00be1a07f0c358b999b3".to_string())
+ );
+ assert!(page.commits[1].parent_ids.is_empty());
+ assert_eq!(page.commits[1].author, "Tom Preston-Werner");
+ assert_eq!(page.commits[1].summary, "initial grit setup");
+ assert_eq!(
+ page.commits[1].time,
+ SystemTime::UNIX_EPOCH + Duration::from_secs(1_191_997_100)
+ );
+ }
+
+ #[test]
+ fn parse_remote_branches_handles_pull_ref_prefixes_from_gitpython_fixture() {
+ let mut output = gitpython_fetch_head_to_remote_ref_output(
+ GITPY_UNCOMMON_BRANCH_PREFIX_FETCH_HEAD,
+ "origin",
+ );
+ output.push_str("origin/HEAD\tdeadbeef\n");
+ let branches = parse_remote_branches(&output);
+
+ let names = branches.iter().map(|b| b.name.as_str()).collect::>();
+ assert_eq!(
+ names,
+ vec![
+ "pull/1/head",
+ "pull/1/merge",
+ "pull/2/head",
+ "pull/2/merge",
+ "pull/3/head",
+ "pull/3/merge",
+ ]
+ );
+ assert_eq!(branches.len(), 6);
+ assert_eq!(
+ branches[0].target,
+ CommitId("c2e3c20affa3e2b61a05fdc9ee3061dd416d915e".to_string())
+ );
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_colon_paths_from_gitpython_fixture() {
+ let raw = String::from_utf8_lossy(GITPY_DIFF_FILE_WITH_COLON);
+ let colon_path = raw
+ .split('\0')
+ .find(|segment| segment.contains("file with : colon.txt"))
+ .expect("fixture contains colon path")
+ .trim();
+
+ let parsed = parse_name_status_line(&format!("M\t{colon_path}"))
+ .expect("name-status line with colon path should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("file with : colon.txt"));
+ assert_eq!(parsed.kind, FileStatusKind::Modified);
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_space_paths_from_gitpython_fixture() {
+ let added_path = GITPY_DIFF_FILE_WITH_SPACES
+ .lines()
+ .find_map(|line| line.strip_prefix("+++ b/"))
+ .expect("fixture contains +++ path line")
+ .trim();
+
+ let parsed = parse_name_status_line(&format!("A\t{added_path}"))
+ .expect("name-status line with spaces should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("file with spaces"));
+ assert_eq!(parsed.kind, FileStatusKind::Added);
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_unicode_rename_from_gitpython_fixture() {
+ let from = GITPY_DIFF_RENAME
+ .lines()
+ .find_map(|line| line.strip_prefix("rename from "))
+ .expect("fixture contains rename-from line")
+ .trim();
+ let to = GITPY_DIFF_RENAME
+ .lines()
+ .find_map(|line| line.strip_prefix("rename to "))
+ .expect("fixture contains rename-to line")
+ .trim();
+
+ let parsed = parse_name_status_line(&format!("R100\t{from}\t{to}"))
+ .expect("rename name-status line should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("müller"));
+ assert_eq!(parsed.kind, FileStatusKind::Renamed);
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_copy_status_from_gitpython_raw_fixture() {
+ let line = gitpython_raw_to_name_status_line(GITPY_DIFF_COPIED_MODE_RAW.trim());
+ let parsed = parse_name_status_line(&line).expect("copied raw status should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("test2.txt"));
+ assert_eq!(parsed.kind, FileStatusKind::Added);
+ }
+
+ #[test]
+ fn parse_name_status_line_maps_type_change_to_modified_from_gitpython_raw_fixture() {
+ let line = gitpython_raw_to_name_status_line(GITPY_DIFF_CHANGE_IN_TYPE_RAW.trim());
+ let parsed = parse_name_status_line(&line).expect("type-change raw status should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("this"));
+ assert_eq!(parsed.kind, FileStatusKind::Modified);
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_raw_rename_from_gitpython_fixture() {
+ let line = gitpython_raw_to_name_status_line(GITPY_DIFF_RENAME_RAW.trim());
+ let parsed = parse_name_status_line(&line).expect("rename raw status should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("that"));
+ assert_eq!(parsed.kind, FileStatusKind::Renamed);
+ }
+
+ #[test]
+ fn parse_name_status_line_handles_raw_binary_modified_from_gitpython_fixture() {
+ let line = gitpython_raw_to_name_status_line(GITPY_DIFF_RAW_BINARY.trim());
+ let parsed = parse_name_status_line(&line).expect("binary raw status should parse");
+
+ assert_eq!(parsed.path, PathBuf::from("rps"));
+ assert_eq!(parsed.kind, FileStatusKind::Modified);
+ }
+
+ #[test]
+ fn parse_name_status_line_preserves_single_space_path_from_gitpython_raw_fixture() {
+ let raw = GITPY_DIFF_INDEX_RAW.trim_end_matches('\n');
+ let status_start = raw
+ .find(" D\t")
+ .map(|ix| ix + 1)
+ .expect("fixture should contain deleted status with tab-separated path");
+ let line = &raw[status_start..];
+
+ let parsed = parse_name_status_line(line).expect("single-space path should parse");
+ assert_eq!(parsed.path, PathBuf::from(" "));
+ assert_eq!(parsed.kind, FileStatusKind::Deleted);
+ }
+
+ #[test]
+ fn parse_name_status_line_preserves_unsafe_paths_from_gitpython_patch_fixture() {
+ let paths = gitpython_patch_b_paths(GITPY_DIFF_PATCH_UNSAFE_PATHS);
+ assert!(paths.iter().any(|p| p == "path/ starting with a space"));
+ assert!(paths.iter().any(|p| p == "path/ending in a space "));
+ assert!(paths.iter().any(|p| p == r#"path/with\ttab"#));
+ assert!(paths.iter().any(|p| p == r#"path/with\nnewline"#));
+ assert!(paths.iter().any(|p| p == "path/with spaces"));
+ assert!(paths.iter().any(|p| p == "path/with-question-mark?"));
+
+ for path in paths {
+ let parsed = parse_name_status_line(&format!("A\t{path}"))
+ .expect("unsafe path from fixture should parse");
+ assert_eq!(parsed.path, PathBuf::from(&path));
+ assert_eq!(parsed.kind, FileStatusKind::Added);
+ }
+ }
}
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/README.md b/crates/gitgpui-git-gix/tests/fixtures/gitpython/README.md
new file mode 100644
index 0000000..1d416bc
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/README.md
@@ -0,0 +1,18 @@
+# GitPython Fixture Imports
+
+These files are copied from `GitPython/test/fixtures` and are used in
+`gitgpui-git-gix` parser tests to validate edge cases that also matter for
+gitgpui:
+
+- ref names with path components (`for_each_ref_with_path_component`)
+- paths containing spaces (`diff_file_with_spaces`)
+- paths containing `:` (`diff_file_with_colon`)
+- unicode rename paths (`diff_rename`)
+- additional raw status kinds (`diff_copied_mode_raw`, `diff_change_in_type_raw`,
+ `diff_rename_raw`, `diff_raw_binary`, `diff_index_raw`)
+- unsafe/quoted path variants from patch output (`diff_patch_unsafe_paths`)
+- uncommon pull-style ref prefixes (`uncommon_branch_prefix_FETCH_HEAD`)
+- commit metadata fixtures used for log pretty-format parsing (`rev_list_single`,
+ `rev_list_commit_stats`)
+- `git blame --line-porcelain` parsing (`blame`, `blame_complex_revision`,
+ `blame_binary`)
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame
new file mode 100644
index 0000000..10c141d
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame
@@ -0,0 +1,131 @@
+634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7
+author Tom Preston-Werner
+author-mail
+author-time 1191997100
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1191997100
+committer-tz -0700
+filename lib/grit.rb
+summary initial grit setup
+boundary
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
+634396b2f541a9f2d58b00be1a07f0c358b999b3 2 2
+
+634396b2f541a9f2d58b00be1a07f0c358b999b3 3 3
+ # core
+634396b2f541a9f2d58b00be1a07f0c358b999b3 4 4
+
+634396b2f541a9f2d58b00be1a07f0c358b999b3 5 5
+ # stdlib
+634396b2f541a9f2d58b00be1a07f0c358b999b3 6 6
+
+634396b2f541a9f2d58b00be1a07f0c358b999b3 7 7
+ # internal requires
+3b1930208a82457747d76729ae088e90edca4673 8 8 1
+author Tom Preston-Werner
+author-mail
+author-time 1192267241
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192267241
+committer-tz -0700
+filename lib/grit.rb
+summary big refactor to do lazy loading
+ require 'grit/lazy'
+4c8124ffcf4039d292442eeccabdeca5af5c5017 8 9 1
+author Tom Preston-Werner
+author-mail
+author-time 1191999972
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1191999972
+committer-tz -0700
+filename lib/grit.rb
+summary implement Grit#heads
+ require 'grit/errors'
+d01a4cfad6ea50285c4710243e3cbe019d381eba 9 10 1
+author Tom Preston-Werner
+author-mail
+author-time 1192032303
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192032303
+committer-tz -0700
+filename lib/grit.rb
+summary convert to Grit module, refactor to be more OO
+ require 'grit/git'
+4c8124ffcf4039d292442eeccabdeca5af5c5017 9 11 1
+ require 'grit/head'
+a47fd41f3aa4610ea527dcc1669dfdb9c15c5425 10 12 1
+author Tom Preston-Werner
+author-mail
+author-time 1192002639
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192002639
+committer-tz -0700
+filename lib/grit.rb
+summary add more comments throughout
+ require 'grit/commit'
+b17b974691f0a26f26908495d24d9c4c718920f8 13 13 1
+author Tom Preston-Werner
+author-mail
+author-time 1192271832
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192271832
+committer-tz -0700
+filename lib/grit.rb
+summary started implementing Tree
+ require 'grit/tree'
+74fd66519e983a0f29e16a342a6059dbffe36020 14 14 1
+author Tom Preston-Werner
+author-mail
+author-time 1192317005
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192317005
+committer-tz -0700
+filename lib/grit.rb
+summary add Blob
+ require 'grit/blob'
+d01a4cfad6ea50285c4710243e3cbe019d381eba 12 15 1
+ require 'grit/repo'
+634396b2f541a9f2d58b00be1a07f0c358b999b3 9 16 1
+
+d01a4cfad6ea50285c4710243e3cbe019d381eba 14 17 1
+ module Grit
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 18 18 6
+author Tom Preston-Werner
+author-mail
+author-time 1192860483
+author-tz -0700
+committer Tom Preston-Werner
+committer-mail
+committer-time 1192860483
+committer-tz -0700
+filename lib/grit.rb
+summary implement Repo.init_bare
+ class << self
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 19 19
+ attr_accessor :debug
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 20 20
+ end
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 21 21
+
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 22 22
+ self.debug = false
+b6e1b765e0c15586a2c5b9832854f95defd71e1f 23 23
+
+634396b2f541a9f2d58b00be1a07f0c358b999b3 11 24 2
+ VERSION = '1.0.0'
+634396b2f541a9f2d58b00be1a07f0c358b999b3 12 25
+ end
\ No newline at end of file
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_binary b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_binary
new file mode 100644
index 0000000..db78205
Binary files /dev/null and b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_binary differ
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_complex_revision b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_complex_revision
new file mode 100644
index 0000000..e2de6d3
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/blame_complex_revision
@@ -0,0 +1,177 @@
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 1 1 83
+author Sebastian Thiel
+author-mail
+author-time 1420715996
+author-tz +0100
+committer Sebastian Thiel
+committer-mail
+committer-time 1420716149
+committer-tz +0100
+summary Fixed PY3 support.
+boundary
+filename README.md
+ ## GitPython
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 2 2
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 3 3
+ GitPython is a python library used to interact with git repositories, high-level like git-porcelain, or low-level like git-plumbing.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 4 4
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 5 5
+ It provides abstractions of git objects for easy access of repository data, and additionally allows you to access the git repository more directly using either a pure python implementation, or the faster, but more resource intensive git command implementation.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 6 6
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 7 7
+ The object database implementation is optimized for handling large quantities of objects and large datasets, which is achieved by using low-level structures and data streaming.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 8 8
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 9 9
+ ### REQUIREMENTS
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 10 10
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 11 11
+ * Git ( tested with 1.8.3.4 )
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 12 12
+ * Python Nose - used for running the tests
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 13 13
+ - Tested with nose 1.3.0
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 14 14
+ * Mock by Michael Foord used for tests
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 15 15
+ - Tested with 1.0.1
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 16 16
+ * Coverage - used for tests coverage
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 17 17
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 18 18
+ The list of dependencies are listed in /requirements.txt and /test-requirements.txt. The installer takes care of installing them for you though.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 19 19
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 20 20
+ ### INSTALL
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 21 21
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 22 22
+ [](https://pypi.python.org/pypi/GitPython/)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 23 23
+ [](https://pypi.python.org/pypi/GitPython/)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 24 24
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 25 25
+ If you have downloaded the source code:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 26 26
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 27 27
+ python setup.py install
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 28 28
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 29 29
+ or if you want to obtain a copy from the Pypi repository:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 30 30
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 31 31
+ pip install gitpython
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 32 32
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 33 33
+ Both commands will install the required package dependencies.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 34 34
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 35 35
+ A distribution package can be obtained for manual installation at:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 36 36
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 37 37
+ http://pypi.python.org/pypi/GitPython
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 38 38
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 39 39
+ ### RUNNING TESTS
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 40 40
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 41 41
+ The easiest way to run test is by using [tox](https://pypi.python.org/pypi/tox) a wrapper around virtualenv. It will take care of setting up environnements with the proper dependencies installed and execute test commands. To install it simply:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 42 42
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 43 43
+ pip install tox
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 44 44
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 45 45
+ Then run:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 46 46
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 47 47
+ tox
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 48 48
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 49 49
+ ### SOURCE
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 50 50
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 51 51
+ GitPython's git repo is available on GitHub, which can be browsed at [github](https://github.com/gitpython-developers/GitPython) and cloned like that:
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 52 52
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 53 53
+ git clone git://github.com/gitpython-developers/GitPython.git git-python
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 54 54
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 55 55
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 56 56
+ ### INFRASTRUCTURE
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 57 57
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 58 58
+ * [User Documentation](http://gitpython.readthedocs.org)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 59 59
+ * [Mailing List](http://groups.google.com/group/git-python)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 60 60
+ * [Issue Tracker](https://github.com/gitpython-developers/GitPython/issues)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 61 61
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 62 62
+ ### LICENSE
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 63 63
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 64 64
+ New BSD License. See the LICENSE file.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 65 65
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 66 66
+ ### DEVELOPMENT STATUS
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 67 67
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 68 68
+ [](https://travis-ci.org/gitpython-developers/GitPython)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 69 69
+ [](https://coveralls.io/r/gitpython-developers/GitPython?branch=master)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 70 70
+ [](https://readthedocs.org/projects/gitpython/?badge=stable)
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 71 71
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 72 72
+ Now that there seems to be a massive user base, this should be motivation enough to let git-python return to a proper state, which means
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 73 73
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 74 74
+ * no open pull requests
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 75 75
+ * no open issues describing bugs
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 76 76
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 77 77
+ #### FUTURE GOALS
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 78 78
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 79 79
+ There has been a lot of work in the master branch, which is the direction I want git-python to go. Namely, it should be able to freely mix and match the back-end used, depending on your requirements and environment.
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 80 80
+
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 81 81
+ * make new master work similarly to 0.3, but with the option to swap for at least one additional backend
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 82 82
+ * make a 1.0 release
+e40ad6369bc74d01af4dc41d3a9b8e25ac2aa01e 83 83
+ * add backends as required
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_change_in_type_raw b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_change_in_type_raw
new file mode 100644
index 0000000..0793e1b
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_change_in_type_raw
@@ -0,0 +1 @@
+:100644 120000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 42061c01a1c70097d1e4579f29a5adf40abdec95 T this
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_copied_mode_raw b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_copied_mode_raw
new file mode 100644
index 0000000..7640f3a
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_copied_mode_raw
@@ -0,0 +1 @@
+:100644 100644 cfe9deac6e10683917e80f877566b58644aa21df cfe9deac6e10683917e80f877566b58644aa21df C100 test1.txt test2.txt
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_colon b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_colon
new file mode 100644
index 0000000..4058b17
Binary files /dev/null and b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_colon differ
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_spaces b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_spaces
new file mode 100644
index 0000000..a9f0b06
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_file_with_spaces
@@ -0,0 +1,7 @@
+diff --git a/file with spaces b/file with spaces
+new file mode 100644
+index 0000000000000000000000000000000000000000..75c620d7b0d3b0100415421a97f553c979d75174
+--- /dev/null
++++ b/file with spaces
+@@ -0,0 +1 @@
++ohai
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_index_raw b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_index_raw
new file mode 100644
index 0000000..c25f380
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_index_raw
@@ -0,0 +1 @@
+:100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_patch_unsafe_paths b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_patch_unsafe_paths
new file mode 100644
index 0000000..1aad675
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_patch_unsafe_paths
@@ -0,0 +1,89 @@
+diff --git a/path/ starting with a space b/path/ starting with a space
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ b/path/ starting with a space
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/\"with-quotes\"" "b/path/\"with-quotes\""
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/\"with-quotes\""
+@@ -0,0 +1 @@
++dummy content
+diff --git a/path/'with-single-quotes' b/path/'with-single-quotes'
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ b/path/'with-single-quotes'
+@@ -0,0 +1 @@
++dummy content
+diff --git a/path/ending in a space b/path/ending in a space
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ b/path/ending in a space
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/with\ttab" "b/path/with\ttab"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/with\ttab"
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/with\nnewline" "b/path/with\nnewline"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/with\nnewline"
+@@ -0,0 +1 @@
++dummy content
+diff --git a/path/with spaces b/path/with spaces
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ b/path/with spaces
+@@ -0,0 +1 @@
++dummy content
+diff --git a/path/with-question-mark? b/path/with-question-mark?
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ b/path/with-question-mark?
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/¯\\_(ツ)_|¯" "b/path/¯\\_(ツ)_|¯"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/¯\\_(ツ)_|¯"
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/\360\237\222\251.txt" "b/path/\360\237\222\251.txt"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/\360\237\222\251.txt"
+@@ -0,0 +1 @@
++dummy content
+diff --git "a/path/\200-invalid-unicode-path.txt" "b/path/\200-invalid-unicode-path.txt"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/\200-invalid-unicode-path.txt"
+@@ -0,0 +1 @@
++dummy content
+diff --git a/a/with spaces b/b/with some spaces
+similarity index 100%
+rename from a/with spaces
+rename to b/with some spaces
+diff --git a/a/ending in a space b/b/ending with space
+similarity index 100%
+rename from a/ending in a space
+rename to b/ending with space
+diff --git "a/a/\"with-quotes\"" "b/b/\"with even more quotes\""
+similarity index 100%
+rename from "a/\"with-quotes\""
+rename to "b/\"with even more quotes\""
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_raw_binary b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_raw_binary
new file mode 100644
index 0000000..d4673fa
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_raw_binary
@@ -0,0 +1 @@
+:100755 100755 f4567df37451b230b1381b1bc9c2bcad76e08a3c 736bd596a36924d30b480942e9475ce0d734fa0d M rps
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename
new file mode 100644
index 0000000..2d5241e
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename
@@ -0,0 +1,12 @@
+commit 2524c44334a8ba6b2ab8f3f0a478f04c5b073cc8
+tree e126e7b4203dadf083f5eb8e2f34c255b51d8bee
+parent d789e23b9ea8d90221d13c46f7c228d729385f92
+author Michael Trier 1229389391 -0500
+committer Michael Trier 1229389391 -0500
+
+ Renamed AUTHORS to CONTRIBUTORS because it's cooler.
+
+diff --git a/AUTHORS b/CONTRIBUTORS
+similarity index 100%
+rename from Jérôme
+rename to müller
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename_raw b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename_raw
new file mode 100644
index 0000000..92d06d2
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/diff_rename_raw
@@ -0,0 +1 @@
+:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 R100 this that
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/for_each_ref_with_path_component b/crates/gitgpui-git-gix/tests/fixtures/gitpython/for_each_ref_with_path_component
new file mode 100644
index 0000000..e723b4a
Binary files /dev/null and b/crates/gitgpui-git-gix/tests/fixtures/gitpython/for_each_ref_with_path_component differ
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_commit_stats b/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_commit_stats
new file mode 100644
index 0000000..60aa8cf
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_commit_stats
@@ -0,0 +1,7 @@
+commit 634396b2f541a9f2d58b00be1a07f0c358b999b3
+tree b35b4bf642d667fdd613eebcfe4e17efd420fb8a
+author Tom Preston-Werner 1191997100 -0700
+committer Tom Preston-Werner 1191997100 -0700
+
+ initial grit setup
+
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_single b/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_single
new file mode 100644
index 0000000..d8c6431
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/rev_list_single
@@ -0,0 +1,7 @@
+commit 4c8124ffcf4039d292442eeccabdeca5af5c5017
+tree 672eca9b7f9e09c22dcb128c283e8c3c8d7697a4
+parent 634396b2f541a9f2d58b00be1a07f0c358b999b3
+author Tom Preston-Werner 1191999972 -0700
+committer Tom Preston-Werner 1191999972 -0700
+
+ implement Grit#heads
diff --git a/crates/gitgpui-git-gix/tests/fixtures/gitpython/uncommon_branch_prefix_FETCH_HEAD b/crates/gitgpui-git-gix/tests/fixtures/gitpython/uncommon_branch_prefix_FETCH_HEAD
new file mode 100644
index 0000000..7df36f2
--- /dev/null
+++ b/crates/gitgpui-git-gix/tests/fixtures/gitpython/uncommon_branch_prefix_FETCH_HEAD
@@ -0,0 +1,6 @@
+c2e3c20affa3e2b61a05fdc9ee3061dd416d915e 'refs/pull/1/head' of http://github.com/loic-bot/testrepo
+fd8695d980e2c6df62b7785f93fd6292d1e283fb 'refs/pull/1/merge' of http://github.com/loic-bot/testrepo
+bb46faf089720d1a3f9e4dc3b11ed5ff77d7e764 'refs/pull/2/head' of http://github.com/loic-bot/testrepo
+5faa366d58454eceea811e0e34c502bdd7b37e4b 'refs/pull/2/merge' of http://github.com/loic-bot/testrepo
+b3ad3c4f1864b50d4d3e09320947a1a3c34c9ea2 'refs/pull/3/head' of http://github.com/loic-bot/testrepo
+71fe57e511776042b009ed4bb281b62b0522b434 'refs/pull/3/merge' of http://github.com/loic-bot/testrepo
diff --git a/crates/gitgpui-ui-gpui/assets/icons/gitgpui_mark.svg b/crates/gitgpui-ui-gpui/assets/icons/gitgpui_mark.svg
index 8c7eec7..9411e94 100644
--- a/crates/gitgpui-ui-gpui/assets/icons/gitgpui_mark.svg
+++ b/crates/gitgpui-ui-gpui/assets/icons/gitgpui_mark.svg
@@ -1,12 +1,3 @@
-
+
\ No newline at end of file
diff --git a/crates/gitgpui-ui-gpui/src/assets.rs b/crates/gitgpui-ui-gpui/src/assets.rs
index 5547745..00d453f 100644
--- a/crates/gitgpui-ui-gpui/src/assets.rs
+++ b/crates/gitgpui-ui-gpui/src/assets.rs
@@ -6,11 +6,11 @@ pub struct GitGpuiAssets;
impl GitGpuiAssets {
fn load_static(path: &str) -> Option> {
match path {
- "gitgpui_logo.svg" => Some(Cow::Borrowed(include_bytes!(
- "../../../assets/gitgpui_logo.svg"
+ "gitcomet-512.svg" => Some(Cow::Borrowed(include_bytes!(
+ "../../../assets/gitcomet-512.svg"
))),
- "gitgpui_logo_window.svg" => Some(Cow::Borrowed(include_bytes!(
- "../../../assets/gitgpui_logo_window.svg"
+ "gitcomet_logo_window.svg" => Some(Cow::Borrowed(include_bytes!(
+ "../../../assets/gitcomet_logo_window.svg"
))),
"icons/arrow_down.svg" => Some(Cow::Borrowed(include_bytes!(
"../assets/icons/arrow_down.svg"
@@ -62,8 +62,8 @@ impl GitGpuiAssets {
fn list_static(dir: &str) -> Vec {
match dir.trim_end_matches('/') {
"" => vec![
- "gitgpui_logo.svg".into(),
- "gitgpui_logo_window.svg".into(),
+ "gitcomet-512.svg".into(),
+ "gitcomet_logo_window.svg".into(),
"icons".into(),
],
"icons" => vec![
diff --git a/crates/gitgpui-ui-gpui/src/view/chrome.rs b/crates/gitgpui-ui-gpui/src/view/chrome.rs
index 3b1e1b4..4b2b4b5 100644
--- a/crates/gitgpui-ui-gpui/src/view/chrome.rs
+++ b/crates/gitgpui-ui-gpui/src/view/chrome.rs
@@ -34,13 +34,9 @@ fn titlebar_app_icon(theme: AppTheme) -> AnyElement {
.id("titlebar_app_icon")
.size(px(16.0))
.rounded(px(4.0))
- .bg(with_alpha(
- theme.colors.text,
- if theme.is_dark { 0.12 } else { 0.08 },
- ))
.overflow_hidden()
.child(
- gpui::img("gitgpui_logo_window.svg")
+ gpui::img("gitcomet_logo_window.svg")
.size(px(16.0))
.object_fit(ObjectFit::Contain)
.with_fallback(move || {
diff --git a/crates/gitgpui-ui-gpui/src/view/linux_desktop_integration.rs b/crates/gitgpui-ui-gpui/src/view/linux_desktop_integration.rs
index 60dcca9..f54f4ec 100644
--- a/crates/gitgpui-ui-gpui/src/view/linux_desktop_integration.rs
+++ b/crates/gitgpui-ui-gpui/src/view/linux_desktop_integration.rs
@@ -31,7 +31,7 @@ impl GitGpuiView {
};
let desktop_path = data_home.join("applications/gitgpui.desktop");
- let icon_path = data_home.join("icons/hicolor/scalable/apps/gitgpui.svg");
+ let icon_path = data_home.join("icons/hicolor/scalable/apps/gitcomet-512.svg");
if desktop_path.exists() && icon_path.exists() {
return;
}
@@ -58,7 +58,7 @@ impl GitGpuiView {
));
const ICON_SVG: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
- "/../../assets/gitgpui_logo.svg"
+ "/../../assets/gitcomet-512.svg"
));
let exe = std::env::current_exe().map_err(|_| {
@@ -76,7 +76,7 @@ impl GitGpuiView {
let applications_dir = data_home.join("applications");
let icons_dir = data_home.join("icons/hicolor/scalable/apps");
let desktop_path = applications_dir.join("gitgpui.desktop");
- let icon_path = icons_dir.join("gitgpui.svg");
+ let icon_path = icons_dir.join("gitcomet-512.svg");
fs::create_dir_all(&applications_dir)
.and_then(|_| fs::create_dir_all(&icons_dir))
diff --git a/scripts/install-linux.sh b/scripts/install-linux.sh
index 73bbb07..6dfb032 100755
--- a/scripts/install-linux.sh
+++ b/scripts/install-linux.sh
@@ -8,7 +8,7 @@ Usage: scripts/install-linux.sh [--release|--debug] [--prefix PATH] [--no-build]
Installs:
- binary to /bin/gitgpui-app
- desktop entry to ~/.local/share/applications/gitgpui.desktop
- - icon to ~/.local/share/icons/hicolor/scalable/apps/gitgpui.svg
+ - icon to ~/.local/share/icons/hicolor/scalable/apps/gitcomet-512.svg
Defaults:
--release, --prefix ~/.local, build if needed
@@ -56,8 +56,8 @@ sed "s|^Exec=.*$|Exec=${bindir}/gitgpui-app|g" \
"${repo_root}/assets/linux/gitgpui.desktop" >"$tmp_desktop"
install -Dm644 "$tmp_desktop" "${appdir}/gitgpui.desktop"
-install -Dm644 "${repo_root}/assets/gitgpui_logo.svg" \
- "${icondir}/gitgpui.svg"
+install -Dm644 "${repo_root}/assets/gitcomet-512.svg" \
+ "${icondir}/gitcomet-512.svg"
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$appdir" >/dev/null 2>&1 || true
command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache "${XDG_DATA_HOME:-${HOME}/.local/share}/icons/hicolor" >/dev/null 2>&1 || true
@@ -65,5 +65,5 @@ command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache "${XDG
echo "Installed GitGpui:"
echo " ${bindir}/gitgpui-app"
echo " ${appdir}/gitgpui.desktop"
-echo " ${icondir}/gitgpui.svg"
+echo " ${icondir}/gitcomet-512.svg"
echo "If GNOME still shows a generic icon, log out/in (or restart GNOME Shell)."
diff --git a/scripts/uninstall-linux.sh b/scripts/uninstall-linux.sh
index 0e2616f..8e50f85 100755
--- a/scripts/uninstall-linux.sh
+++ b/scripts/uninstall-linux.sh
@@ -19,7 +19,7 @@ icondir="${XDG_DATA_HOME:-${HOME}/.local/share}/icons/hicolor/scalable/apps"
rm -f "${bindir}/gitgpui-app"
rm -f "${appdir}/gitgpui.desktop"
-rm -f "${icondir}/gitgpui.svg"
+rm -f "${icondir}/gitcomet-512.svg"
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$appdir" >/dev/null 2>&1 || true
command -v gtk-update-icon-cache >/dev/null 2>&1 && gtk-update-icon-cache "${XDG_DATA_HOME:-${HOME}/.local/share}/icons/hicolor" >/dev/null 2>&1 || true