Skip to content

Issue performing interactive rebases #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oskarpearson opened this issue May 5, 2015 · 15 comments · May be fixed by #162 or #210
Closed

Issue performing interactive rebases #53

oskarpearson opened this issue May 5, 2015 · 15 comments · May be fixed by #162 or #210

Comments

@oskarpearson
Copy link

Hi

I was wondering if there is a known problem with interactive rebasing? This happens on a freshly-cloned repo containing git-crypt objects:

$ git clone [email protected]:user/somethinghere.git
$ cd somethinghere
$ git checkout some_branch_name
Switched to branch 'some_branch_name'
Your branch is up-to-date with 'origin/some_branch_name'.
$ git status
On branch some_branch_name
Your branch is up-to-date with 'origin/some_branch_name'.
nothing to commit, working directory clean
$ git rebase -i HEAD~5
Cannot rebase: You have unstaged changes.
Please commit or stash them.
$ git status
On branch some_branch_name
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Unfortunately I can't share the actual repo that has the issue.

Environment:

  • git-crypt 0.4.2
  • Mac os 10.10.3
  • git version 2.4.0

Thanks for your time!

@AGWA
Copy link
Owner

AGWA commented May 6, 2015

Just to be clear, those are the exact sequence of commands you're running? git-crypt unlock or git-crypt init were not run between cloning and rebasing? Because if they weren't, then git-crypt isn't even set up in this repository so there's no way git-crypt could be causing this problem.

@oskarpearson
Copy link
Author

Hi

Gah - I did the worst possible thing for submitting a support ticket - leaving out steps. Sorry about that. I was hoping you'd immediately say 'yep, it's a known issue' or 'no, there's no issue'

Oskars-MacBook-Pro:junk-me oskar$ git clone [email protected]:someuser/someproject.git
Cloning into 'someproject'...
remote: Counting objects: 255, done.
remote: Compressing objects: 100% (73/73), done.
remote: Total 255 (delta 28), reused 7 (delta 7), pack-reused 172
Receiving objects: 100% (255/255), 117.87 KiB | 66.00 KiB/s, done.
Resolving deltas: 100% (68/68), done.
Checking connectivity... done.
Oskars-MacBook-Pro:junk-me oskar$ cd someproject
(reverse-i-search)`':
Oskars-MacBook-Pro:someproject oskar$ git-crypt unlock

You need a passphrase to unlock the secret key for
user: "Oskar Stephen Pearson <[email protected]>"
4096-bit RSA key, ID 8682D468, created 2013-07-11 (main key ID 8A693BAF)

Oskars-MacBook-Pro:someproject oskar$ git checkout somebranch
Branch somebranch set up to track remote branch somebranch from origin.
Switched to a new branch 'somebranch'
Oskars-MacBook-Pro:someproject oskar$ git rebase -i HEAD~3
Cannot rebase: You have unstaged changes.
Please commit or stash them.
Oskars-MacBook-Pro:someproject oskar$

Oskar

@AGWA
Copy link
Owner

AGWA commented May 6, 2015

Thanks for clarifying that. No, this isn't a known issue, and I'm able to do interactive rebases with Git 2.4.0 without issue.

Was the .git-crypt directory or any .gitattributes file modified in the range of commits you're trying to rebase? You can run git diff --stat HEAD~3.. to get a list of files that were modified.

@oskarpearson
Copy link
Author

Hi

I'm almost certain this has to do with an encrypted zero-byte file in the repository. I've re-created the problem as per the below:

General initiation:

Oskars-MacBook-Pro:junk-me oskar$ mkdir git-crypt-bug-53
Oskars-MacBook-Pro:junk-me oskar$ cd git-crypt-bug-53
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git init .
Initialized empty Git repository in /Users/oskar/Desktop/junk-me/git-crypt-bug-53/.git/
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git-crypt init
Generating key...
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ cat > .gitattributes
secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git add -A
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git-crypt add-gpg-user E93E631C8A693BAF
[master (root-commit) 2a89cea] Add 1 git-crypt collaborator
 2 files changed, 1 insertion(+)
 create mode 100644 .git-crypt/.gitattributes
 create mode 100644 .git-crypt/keys/default/0/49E686824F50A52AC04723D2E93E631C8A693BAF.gpg
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git commit -m "Git and git-crypt init" -a
[master a29c1fb] Git and git-crypt init
 1 file changed, 3 insertions(+)
 create mode 100644 .gitattributes
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ touch zero-byte-file.key
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git add -A
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git commit -m "Added zero byte file" -a
[master 6fb1077] Added zero byte file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 zero-byte-file.key

After the above, here's the status:

Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git-crypt status
not encrypted: .git-crypt/.gitattributes
not encrypted: .git-crypt/keys/default/0/49E686824F50A52AC04723D2E93E631C8A693BAF.gpg
not encrypted: .gitattributes
    encrypted: zero-byte-file.key

Now try create a branch and make some changes:

Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git checkout -b some-branch
Switched to a new branch 'some-branch'
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ echo whatever > whatever.txt
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git add whatever.txt
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git commit -m 'whatever' -a
[some-branch 6a4de09] whatever
 1 file changed, 1 insertion(+)
 create mode 100644 whatever.txt

Status before the rebase - everything looks ok:

Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git status
On branch some-branch
nothing to commit, working directory clean
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git-crypt status
not encrypted: .git-crypt/.gitattributes
not encrypted: .git-crypt/keys/default/0/49E686824F50A52AC04723D2E93E631C8A693BAF.gpg
not encrypted: .gitattributes
not encrypted: whatever.txt
    encrypted: zero-byte-file.key

Now, try rebase and we get the error:

Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git rebase master
**Cannot rebase: You have unstaged changes.**
Please commit or stash them.
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git status
On branch some-branch
nothing to commit, working directory clean
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$ git-crypt status
not encrypted: .git-crypt/.gitattributes
not encrypted: .git-crypt/keys/default/0/49E686824F50A52AC04723D2E93E631C8A693BAF.gpg
not encrypted: .gitattributes
not encrypted: whatever.txt
    encrypted: zero-byte-file.key
Oskars-MacBook-Pro:git-crypt-bug-53 oskar$

It's also worth noting that if I view the directory in textmate, the zero-byte-file.key file appears to have uncommitted changes - despite what 'git status' says.

@oskarpearson
Copy link
Author

Just to add an explanation of why we have zero-byte encrypted files (which is indeed pretty odd). We've encrypted everything in a python source code directory. That includes the __init__.py file - which is normally a zero-byte file.

@AGWA
Copy link
Owner

AGWA commented May 14, 2015

Reproduced with an empty file - nice work tracking this down! I'm now debugging...

@bosgood
Copy link

bosgood commented Nov 9, 2015

@AGWA Hi, I'm running into this issue as well. Would having more information help?

@emkael
Copy link

emkael commented Mar 30, 2016

Hi, I've run into this issue, too - while setting up git-crypt for an etckeeper repository.

It seems that all these zero-byte files misbehave not only on rebase attempt.
If you actually stash the changes as the rebase message suggests, and then pop the stash back to the repository, all the zero-byte files are restored unencrypted (all contain 'GITCRYPT' and the same small chunk of binary data) - but I'm guessing it's a side effect of the fact that they shouldn't have been stashed in the first place.

@theckman
Copy link

theckman commented Jun 3, 2017

I've run in to this issue as well, and the issue is pretty hard to track down if the zero-length file gets introduced in a repo that's had quite a few changes / encrypted files.

I've been thinking about how to surface this issue to consumers until the bug is fixed. It'd be nice if git-crypt status would print a warning at the end of its output to indicate a file of zero-length has been discovered.

@AGWA have you had the spare time or any luck tracking down the root cause for this?

@nielssorensen
Copy link

In the process of looking for a solution, I came across 'git diff-files' which exposed the zero byte files encountered in my repo. (From a stackoverflow page.)

To paraphrase the answer, "git rebase is a shell script. grep it for 'have unstaged changes' and you will find the function require_clean_work_tree, which in turn runs 'git diff-files'."

It hasn't helped resolve any issue, but if you are confounded by the message, hopefully this will expose the affected files.

@hugopeixoto
Copy link

I think these may help track the problem down:

Could the issue be solved by not encrypting zero byte files? Encryption is deterministic, so it shouldn't be a security issue.

@krish7919
Copy link
Contributor

This is a stopper in using git-crypt.

I was just tried git-crypt in our workflow, and it seems that this not only fails the rebase, but also does not show any changes in git status, resulting in the 0B file to be committed to the repo, thereby losing all data.

AGWA added a commit that referenced this issue Jul 29, 2020
git has several problems with using smudge/clean filters
on empty files (see issue #53).  The easiest fix is to
just not encrypt empty files. Since it was already obvious
from the encrypted file length that a file was empty, skipping
empty files does not decrease security.

Since skipping empty files is a breaking change to the
git-crypt file format, we only do this on new repositories.
Specifically, we add a new critical header field to the key
file called skip_empty which is set in new keys.  We
skip empty files if and only if this field is present.

Closes: #53
Closes: #162
@nkrot
Copy link

nkrot commented Dec 13, 2023

Hi @oskarpearson , how did you manage to solve the problem? I guess you did because you closed the issue.

I am in a similar situation: I added empty files initially to the repo, then added content to these files and now I can not rebase. Git detects something and tells me to stash, but stashing does not change anything because there is nothing to stash. I dont even know how to proceed in this situation.

Could you describe the steps you took to get out of this situation? thanks in advance

@oskarpearson
Copy link
Author

Hi @nkrot

I've not used git-crypt for a few years, and it seemed like the above commit should resolve the issues, so I thought it best to close it. You're welcome to re-open it.

@x-yuri
Copy link

x-yuri commented May 28, 2024

In case someone wonders what to do if you forgot to encrypt a file, here's a gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
10 participants