xeor
xeor

Reputation: 5465

What will `git reset --hard` change for me?

I have a setup (it needs to be this way), where I am syncing updated files to a git repository. This happens when files changes, and the .git folder is ignored in this sync process.

so

Some times, I need to update git on server based on upstream, so I am using git fetch --all && git reset --hard origin/branchname. Which work for this purpose.

However, I want to be able to detect, if this actually updated any files or not. In other words, if the client file sync is up to date with the upstream git repo, I want to detect it..

The closest way to do this as I could find is an answer here which are using something like git merge-tree $(git merge-base FETCH_HEAD master) FETCH_HEAD master. The problem with that is that it shows changes, even if the file and content already exist...

updated with testcase

$ { ~/repos }$ mkdir a && cd a

$ { ~/repos/a }$ git init
Initialized empty Git repository in ~/repos/a/.git/

$ { ~/repos/a }$ echo file1 > f1 && git add f1 && git commit -m "1"
[master (root-commit) 9b1b025] ..
 1 file changed, 1 insertion(+)
 create mode 100644 f1

$ { ~/repos }$ git clone a b
Cloning into 'b'...
done.

$ { ~/repos }$ cd b

$ { ~/repos/b }$ ls
f1

$ { ~/repos/a }$ echo file2 > f2 && git add f2 && git commit -m "2"
[master 4e40da5] 2
 1 file changed, 1 insertion(+)
 create mode 100644 f2

$ { ~/repos/b }$ git fetch --all
Fetching origin
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ~/repos/a
   9b1b025..4e40da5  master     -> origin/master

# The folder `b` started with 1 file `f1`, and it can now
# see the new file `f2` as expected.
$ { ~/repos/b }$ git diff HEAD..origin/master
diff --git a/f2 b/f2
new file mode 100644
index 0000000..6c493ff
--- /dev/null
+++ b/f2
@@ -0,0 +1 @@
+file2

# Without using git (another file sync job, think rsync),
# the `f2` is created identical, but without informing git.
# After this, the repos contains the exact same data,
# but git doesn't know that.
$ { ~/repos/b }$ echo file2 > f2

# However, git diff still thinks this file is new..
# At this point, I want to be able to see if
# the origin/master is identical to the content of this repository.
$ { ~/repos/b }$ git diff HEAD..origin/master
diff --git a/f2 b/f2
new file mode 100644
index 0000000..6c493ff
--- /dev/null
+++ b/f2
@@ -0,0 +1 @@
+file2

# Untill I do a reset --hard
$ { ~/repos/b }$ git reset --hard origin/master
HEAD is now at 4e40da5 2

# Doesn't show any output
$ { ~/repos/b }$ git diff HEAD..origin/master

Upvotes: 1

Views: 106

Answers (2)

Sajib Khan
Sajib Khan

Reputation: 24204

You can see the diff between origin/master and HEAD before reset.

$ git fetch --all
$ git diff HEAD..origin/master        # see what is in origin/master that is not in HEAD (local latest commit)

$ git diff origin/master..HEAD        # see what is in HEAD that is not in origin/master

# If local uncommitted changes exist (tracked by git)
$ git diff origin/master

# for untracked/new files, one way is to use '-N' flag with 'git add' command
$ git add -N .
$ git diff origin/master

More about '-N': $ git add --help

  -N, --intent-to-add
       Record only the fact that the path will be added later. An entry for the path
       is placed in the index with no content. This is useful for, among other
       things, showing the unstaged content of such files with git diff and
       committing them with git commit -a.

Upvotes: 1

jthill
jthill

Reputation: 60585

Just have the server do a checkout (by SHA) in post-receive and do your step 1 with git push. "File sync (ignoring .git)" while only doing it when something changed is exactly what pushing committed changes does.

Upvotes: 0

Related Questions