I have a file with a one-line change: git status
reports
S:\mydir\AEL>git status CodingTools_SourceControl.ael
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CodingTools_SourceControl.ael
no changes added to commit (use "git add" and/or "git commit -a")
And here is the change that diff
reports
S:\mydir\AEL>git diff CodingTools_SourceControl.ael
diff --git a/AEL/CodingTools_SourceControl.ael b/AEL/CodingTools_SourceControl.ael
index 7ae86d7..fd53caa 100644
--- a/AEL/CodingTools_SourceControl.ael
+++ b/AEL/CodingTools_SourceControl.ael
@@ -22,7 +22,7 @@ import ael
import acm
is_64_bit = True
-# Special-purpose overrides
+# Special-purpose overrides. These deliberately require minor code changes.
#CodingTools_PyLint.VERBOSE = True
#CodingTools_PyLint.PYLINTRC = "default.pylintrc"
Now I stage my change:
S:\mydir\AEL>git add CodingTools_SourceControl.ael
S:\mydir\AEL>git status CodingTools_SourceControl.ael
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: CodingTools_SourceControl.ael
And if I ask for a report on the staged change I see the same one-line change:
S:\mydir\AEL>git diff --cached CodingTools_SourceControl.ael
diff --git a/AEL/CodingTools_SourceControl.ael b/AEL/CodingTools_SourceControl.ael
index 7ae86d7..fd53caa 100644
--- a/AEL/CodingTools_SourceControl.ael
+++ b/AEL/CodingTools_SourceControl.ael
@@ -22,7 +22,7 @@ import ael
import acm
is_64_bit = True
-# Special-purpose overrides
+# Special-purpose overrides. These deliberately require minor code changes.
#CodingTools_PyLint.VERBOSE = True
#CodingTools_PyLint.PYLINTRC = "default.pylintrc"
Now I unstage the change
S:\PrimeObjects\ADSO71\KEATING\AEL>git reset CodingTools_SourceControl.ael
Unstaged changes after reset:
M AEL/ATS_SourceControl.ael
...several other unstaged changes...
I want to be able to use Dulwich to manage staging and commits. So inside Idle, after the reset
, I do this:
>>> from dulwich.repo import Repo
>>> repo = Repo(br"S:\mydir")
>>> repo.stage([br"AEL\CodingTools_SourceControl.ael"])
After that, git status
shows the change as staged, just like before
S:\mydir\AEL>git status CodingTools_SourceControl.ael
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: CodingTools_SourceControl.ael
But if I now issue a git diff
command, I get a diff report that shows all 1500+ lines of the file as changed:
S:\mydir\AEL>git diff --cached --stat CodingTools_SourceControl.ael
AEL/CodingTools_SourceControl.ael | 3082 ++++++++++++++++++-------------------
1 file changed, 1541 insertions(+), 1541 deletions(-)
Edit: Following up on @RomainVALERI's helpful comment, I tried this command
S:\mydir\AEL>git diff --cached --stat --ignore-cr-at-eol CodingTools_SourceControl.ael
AEL/CodingTools_SourceControl.ael | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
and it reports one line changed. So it is a line-ending problem. But I need Dulwich operations to be interchangeable with command-line operations. How do I tell Dulwich Repo.stage()
to treat line endings the way git add
does?
I tried using porcelain.add()
instead of Repo.stage()
porcelain.add(repo, r"S:\mydir\AEL\CodingTools_SourceControl.ael")
but it didn't help any.
From the code in
dulwich.index.blob_from_path_and_stat()
it appears that Dulwich pays no attention to thecore.autocrlf
setting and pays no attention to anything in the.gitattributes
file and simply writes a byte-for-byte copy of whatever is in the working directory file to the Git database.So Dulwich 0.19.5 and Windows are not a good match if your team will also use other tools that are aware of line-ending policies and apply them in the way that Git does. A later version may well address this, but for now it's oil and water.
As a Git beginner I found Mind the end of your line by Tim Clem at GitHub the very clearest explanation of the dozen or so I read while trying to understand the issue and solve the problem.