简体   繁体   中英

git difference does not work properly after git clone

I have a bash script in which I have to clone and get difference of some repositories. I am trying to get difference between range of a date

git clone $repository 
cd $path
git diff master@{2019-10-1}..master@{2019-10-14} -- package.json

but it shows error: warning: Log for 'master' only goes back to Tue, 15 Oct 2019 09:51:16 +0000.

But this repository is old and has many commits. when I do it locally on the machine in which I had cloned same repository some weeks back I get proper difference.

$ git diff master@{2019-10-1}..master@{2019-10-14} -- package.json
diff --git a/package.json b/package.json
index d29ffcb..8766fde 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "accountd",
-  "version": "0.0.95",
+  "version": "0.0.102",
   "main": "dist/src/index.js",
   "private": true,
   "scripts": {
@@ -8,7 +8,8 @@
     "start-dev": "npm run build && nodemon . port=5000 stage",
     "start-sand": "npm run build && nodemon . port=5000 stage",
-    "test": "nyc --extension .ts --reporter=html --reporter=cobertura --reporter=text mocha -r ts-node/register src/**/*.spec.ts --exit",
+    "test": "mocha -r ts-node/register test/**/*.spec.ts  test/**/**/*.spec.ts --exit",

I want the changes made in this specific file over a period of time.

The notation you're using ( master@{<date>} ) says that you want to refer to the version of master on <date> according to the local reflogs . That is, you're saying that you want to know what this particular clone's master ref pointed to on that date - not what of the current master commits had been committed on that date.

And git is telling you "this clone didn't have a master ref on that date".

To do what you mean, you first have to find the last commit before the "then' date, then diff against that. There are a number of ways, but something like

git diff $(git rev-list -n1 --before="<date>" --first-parent master) master

might be more what you want

The @{date} syntax will not get you what you want. I'd go into what you do want, but I got beaten to the answer; see Mark Adelsberger's answer instead. :-)

What to know about the @{...} syntax

With the @{date} syntax, it doesn't matter how old the repository source is. It does not matter how many commits you have. All that matters is what is in this particular clone's so-called reflogs .

Every Git repository—every clone—has its own reflogs. In general, no two different Git repositories will agree as to what goes into the reflogs. The reflogs are not meant for this kind of job. Which kind of job? This kind:

I want the changes made in this specific file over a period of time.

The reflogs tell you absolutely nothing about changes in files, or changes not in files, over time. They tell you about changes in your Git's references over time.

This may leave you puzzling over what, precisely, a ref or reference is. We probably should not go into too much detail here, but every branch name like master is actually a reference whose full spelling is refs/heads/master ; every tag name like v1.2 is a ref whose full spelling is refs/tags/v1.2 ; and every remote-tracking name like origin/master is a ref whose full spelling starts with refs/remotes/ . So they're just a generalization of the various names that humans tend to use, to talk about commits. What Git needs, to talk about commits, is their raw hash IDs. The names are, to some extent, just there so that us weak humans don't have to remember arbitrary, big ugly hash IDs. 1

The key to understanding this, and the @{...} syntax, is to realize that these names—eg, refs/heads/masterchange over time. Right now, your master commit might be a123456... . Yesterday, it might have been some other commit, and tomorrow, it might be yet another commit. Your Git's master will change over time, and every time it does change, your Git keeps a record of what it was . This record only goes back so far: the commits are permanent, but the record of which hash ID master meant, when, is not. Moreover, it's not carried from one clone to another: Every clone's record of what master meant when is private to that one particular Git . In a fresh clone—which has all the commits 2 —there's only one value master has ever had, which is what it has right now.

Note that you can also use @{ number } . This selects the number'th entry in the reflog.

To view the actual reflog for any particular ref, run git reflog ref , eg, git reflog master . The git reflog command has various other sub-commands for dealing with the logs, too. See its documentation for details.


1 The names do have other functions. For much more about this, see Think Like (a) Git .

2 Assuming it's not a shallow clone, that is, and not using some of the new "promisor pack" features that are not yet in general use. Also, if you cloned with -b or --single-branch , or the upstream repository is set up in a less-usual fashion, you might not have a branch named master yet at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM