jelmer / dulwich

Pure-Python Git implementation
https://www.dulwich.io/
Other
2.06k stars 395 forks source link

porcelaine.reset is not deleting files locally #840

Open chrisiweb opened 3 years ago

chrisiweb commented 3 years ago

The command porclain.reset(repo, 'hard', treeish=b'refs/remote/origin/master') is not deleting files locally, if they we're deleted in my remote repo. Everything else (any changed files) works fine and is reseted. Is there a way to solve this problem?

jelmer commented 3 years ago

On Sun, Feb 14, 2021 at 08:49:30AM -0800, chrisiweb wrote:

The command porclain.reset(repo, 'hard', treeish=b'refs/remote/origin/master') is not deleting files locally, if they we're deleted in my remote repo. Everything else (any changed files) works fine and is reseted. Is there a way to solve this problem?

That's correct - "git reset --hard" doesn't delete files either AFAICT.

Jelmer

-- Jelmer Vernooij jelmer@jelmer.uk PGP Key: https://www.jelmer.uk/D729A457.asc

chrisiweb commented 3 years ago

In fact "git reset --hard" does remove files locally if they were deleted in the remote...

jelmer commented 3 years ago

On Sun, Feb 14, 2021 at 09:52:09PM -0800, chrisiweb wrote:

In fact "git reset --hard" does remove files locally if they were deleted in the remote... "git reset --hard" doesn't look at the remotes at all as far as I can tell. Could you post an example script that reproduces this behaviour?

-- Jelmer Vernooij jelmer@jelmer.uk PGP Key: https://www.jelmer.uk/D729A457.asc

chrisiweb commented 3 years ago

Yes i guess this is true, but I believe calling git fetch first, should work. If I call via a python script: repo = porcelain.Repo(path_to_local_repo) porcelain.fetch(repo) porcelain.reset(repo, 'hard', treeish=b'refs/remote/origin/master')

This unfortunately does not remove deleted files. However, if I call: git fetch git reset --hard in the terminal, it works! Where is my mistake? Did I missunderstand something?

jelmer commented 3 years ago

On Mon, Feb 15, 2021 at 06:56:00AM -0800, chrisiweb wrote:

Yes i guess this is true, but I believe calling git fetch first, should work. If I call via a python script: repo = porcelain.Repo(link_to_local_repo) porcelain.fetch(repo) porcelain.reset(repo, 'hard', treeish=b'refs/remote/origin/master')

This unfortunately does not remove deleted files. However, if I call: git fetch git reset --hard in the terminal, it works! Where is my mistake? Did I missunderstand something?

Can you post the exact commands you're running? If I try that here, remotely removed files are not removed locally::

#!/bin/sh
git init 1
cd 1
touch a b
git add a b
git commit -mm a b
cd ..
git clone 1 2
cd 1
rm b
git commit -m "remove b" b
cd ../2
git fetch
git reset --hard
ls

Results in::

Initialized empty Git repository in /tmp/1/.git/
[master (root-commit) eb009e6] m
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
 create mode 100644 b
Cloning into '2'...
done.
[master 0787dad] remove b
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 b
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (2/2), 869 bytes | 869.00 KiB/s, done.
From /tmp/1
   eb009e6..0787dad  master     -> origin/master
HEAD is now at eb009e6 m
a  b

(in other words, b is not deleted)

-- Jelmer Vernooij jelmer@jelmer.uk PGP Key: https://www.jelmer.uk/D729A457.asc

chrisiweb commented 3 years ago

I can reproduce this. However, if I change to

git reset --hard origin/master

in your example it works and b is also deleted in 2. What I actually do (and what works with git but unfortunately not with dulwich.porcelain):

git clone url_to_repo_on_github

I then delete a file directly on Github (in browser) and commit. I then fetch and reset my local repo with:

git fetch git reset --hard origin/master

My local repo is now identical to my repo on Github. (git reset --hard however, does not update anything! Neither changed nor newly created files nor deleted files)

So if my local repo is reseted to origin/master (and not to HEAD) it works with git.

chrisiweb commented 3 years ago

If removing files in the local repo (if they were deleted on the remote repo) - as described above - is not implemented in porcelain.reset(), is there, however, a way to achieve this manually with dulwich/porcelain? I tried hard, but I could not succeed :( Would be really glad for your help...

jelmer commented 3 years ago

On Fri, Feb 19, 2021 at 07:54:33AM -0800, chrisiweb wrote:

If removing files in the local repo (if they were deleted on the remote repo) - as described above - is not implemented in porcelain.reset(), is there, however, a way to achieve this manually with dulwich/porcelain? I tried hard, but I could not succeed :( Would be really glad for your help... Ah, interesting. I guess that means that "git reset" does look at the current working tree to determine what files to remove.

-- Jelmer Vernooij jelmer@jelmer.uk PGP Key: https://www.jelmer.uk/D729A457.asc