- Add
PackIndex.object_sha_at_positionto look up an object by its position in the sorted index, and use it when loading a.bitmapinstead of re-scanning the index for every entry, which made loading quadratic in the pack size, unlike git. (Kartik Kenchi) - Fix applying patches without content changes, such as mode changes and added or deleted empty files. They have no
---/+++lines and failed with "Patch has no file path". (Jelmer Vernooij) - Fix applying binary patches produced by
git diff --binary. Their paths are now taken from thediff --gitline,literaldata is inflated, base85 line lengths are decoded correctly and binary deletions remove the file. (Jelmer Vernooij) - Support
deltabinary patches, binary changes combined with a rename or copy and reverse application of binary patches inapply_patches. (Jelmer Vernooij) - Unquote C-style quoted file names (as git emits for names with special or non-ASCII characters) when parsing patches. (Jelmer Vernooij)
- SECURITY: Validate index paths in sparse checkout, mixed reset,
lfs_pullandlfs_migrate, so that a malicious repository can no longer write files outside the work tree via..entries or symlinks. (Jelmer Vernooij, reported by Choudhry Shehryar) - SECURITY: Don't write through symlinks in
apply_patches. A tracked symlink such astrap -> .git/hooks/pre-commitwas followed when writing, soporcelain.am/apply_patchcould install a hook. Symlinks are now patched as links, like git does, and a patch whose mode doesn't match the type in the work tree or that adds a file over an existing path is refused. (Jelmer Vernooij, reported by @manus-pi) - Apply a mode change in
build_file_from_blobwhen the content is unchanged. (Jelmer Vernooij) - Fix parsing of a rename or copy without content changes followed by another patch, which swallowed the next patch. (Jelmer Vernooij)
- Honour
\ No newline at end of filemarkers when applying patches, which previously made patches to files without a trailing newline fail. (Jelmer Vernooij) - Ignore a
multi-pack-indexentry whose pack has been removed when answering whether an object is present. After a prune the stale index madesha in repo.object_storedisagree withrepo.object_store[sha]. (Kartik Kenchi) - Don't follow a symlink when reading
.gitignoreor.gitattributesfrom the work tree. A tree could point either name at a file outside the repository and have its contents drive dulwich. (Kartik Kenchi) - Honour
GIT_OPTIONAL_LOCKS=0indulwich status, skipping the index stat-cache refresh that would otherwise lock the index. (Jelmer Vernooij, #1861) - Preserve original URL in remote origin configuration when cloning, matching C git behavior. (Suprovo Ghosh, #2428)
- Report conflicts in criss-cross merges where the merge bases disagree on a file. The recursive merge silently kept one base's blob as the virtual base, so the final three-way merge published the other side's content without recording a conflict. (Jelmer Vernooij, #2419)
- Record merge conflicts in the index with stages 1/2/3 and write MERGE_HEAD/MERGE_MSG when
porcelain.mergeleaves conflicts, so the working tree matches git's state andgit commitcan finish the merge. (Jelmer Vernooij) - Preserve index entries that differ only by case when loading the index, resetting mixed, or restoring a stashed index tree under core.ignorecase. (Jelmer Vernooij, #2434)
- Fix a crash in
dulwich log <path>on merge commits where the path is unchanged relative to one parent.tree_changes_for_mergereportsNonefor such parents, which the walker and the--name-statusand--name-onlyoutput wrongly assumed to be aTreeChange. (Jelmer Vernooij, #2412) dulwich log <path>now applies git's default history simplification. Pass--full-historyfor the old behavior.Walkerandget_walkergain asimplify_historyflag. (Jelmer Vernooij, #2414)- Carry the repository's object format through the index and the work tree.
addandcommiton a SHA-256 repository wrote SHA-1 identities into the index, trees and refs, leaving a repository neither dulwich nor git could read back. (Jelmer Vernooij, #2416) - Honour the
eolgitattribute. Line ending conversion is now resolved per path from thetext/crlfandeolattributes, falling back tocore.autocrlfandcore.eolonly where the attributes are silent, soeol=crlfandeol=lftake precedence over the configuration as they do in git. (Jelmer Vernooij, #2403) - Write carriage returns in configuration values literally rather than as a
\rescape. (Jelmer Vernooij) - Strip leading blank lines in
stripspacein a single pass. The previouspop(0)loop made an all-blank input O(n^2); it is now linear like git. (Kartik Kenchi)