简体   繁体   中英

git - how to show list of changed files relative to creation of current branch

I need to be able to see a list of files that have been modified in any way since creation of the current branch, whether committed or staged or just changed in the tree.

My scenario is (chronologically)

1.  clone branch master from remote master
2.  make various changes,  adds and commits in my local master
3.  git branch myisolatedbranch
4.  git checkout myisolatedbranch
5.  make various changes,  adds and commits in myisolatedbranch
6.  git push --all  
             (creates myisolated branch in remote) 
             (don't know if this step 6 is relevant)
7.  make various changes,  adds and commits in myisolatedbranch
  1. and now - I want to see a simple list of files which are different in the working tree now compared to the working tree at time 4. ie what have I changed in myisolatedbranch (not only commits but any changes)

Plain git status tells me the list of all files different compared to time 1, ie what is different in the totality of myisoatedbranch and master, which also includes everything I changed at time 2, which is a lot of files that I do not want to look at.

according to man page for git status , there is an optional positional parm

[<pathspec>…​]

which could possibly help me out - but frustratingly, the man page has nothing to say about the effect of this parameter. (so my second question is , what exactly does this parameter do in this context?)

Or should I be trying git log? But I think that reports only commits.

In Git, branches—or more precisely, branch names —are really almost nothing. Git does not know anything about their creation or, with some exceptions, their history. They either exist now, in which case they point to a (one, single) commit, or they do not exist now, and that's pretty much it. 1

Commits, on the other hand, are forever (with some exceptions since otherwise you could never make temporary commits, and Git makes a lot of temporary commits). The problem with commits, which are permanent as long as they are reachable —a notion that requires a lot of defining so I'll just ignore for the moment 2 —is that their names are extremely unfriendly. For instance, consider commit 7446b8fa5ead8ce0990e8f2be3a2490eac8e199f .

What in the name of all that's gitty is 7446b8fa5ead8ce0990e8f2be3a2490eac8e199f ?

Well, you can actually Google it: it's Git version 2.9.0, in the Git repository for Git itself. But "v2.9.0" is a much friendlier name. And, v2.9.0 is a tag in the Git repository for Git, and that tag is (and remembers for you and me) that big ugly 7446 bqhatevwr .

If you want to remember a particular commit—which is what you want here, because you want to compare your current version against "that particular commit I was trying to remember, whatever its big ugly SHA-1 hash was"—then a tag is what you want. Give that commit a tag, and you can then just give that tag name to Git whenever you mean to say "tell me about that commit I had you remember".


1 The weird thing about this—that a branch name merely points to the one branch-tip commit—is that it's actually incredibly useful . The way Git works is that when you're on a branch and make a new commit, Git makes the new commit have the previous branch-tip as its parent commit, and then makes the branch name point to the new commit.

It is therefore possible, with a great deal of effort (which Git automates), to start from any branch-tip commit and build a graph of every commit that came before that commit. Note that this tells you everything about all those commits themselves except what their names were , back when those commits were made. Branch names, by definition, are always changing. This is why we have tag names, which Git never changes itself. If you keep them around, they will provide sensible names for the commits (for some value of "sensible" anyway, depending entirely on your own ability to come up with good names).

2 The notion of reachability boils down, in the end, to using things like branch and tag names as gateways into the commit graph. Once you have the big ugly hash of an object to get started within this graph, you use your now-known commits to obtain parent commit IDs so as to find yet more commits. You then use those commit IDs to find still more parent IDs, until you have found every commit in the graph. (Along the way you use these to find tree objects, and use the trees to find blob objects. There are also tag objects for annotated tags. An annotated tag is just a tag name that points to such an object. The tag object points to the tagged commit, rather than having the tag point directly to the commit. With a lightweight tag , the tag name points directly to the commit.)

Any objects—commits, tags, trees, or blobs—that are in fact stored in Git's object database (in the .git directory containing the repository), but that are not reachable by the above method, are marked for garbage collection via git gc . Therefore, temporary commits can be made whenever you like—there are some extra guarantees, such as "objects linger for 14 days" and "most names have reflogs" and so on that will either keep them reachable for at least a month, or temporarily protect them from the Grim Reaper—and then, if you decide you like them after all, give them external names such as branch and/or tag names. If you decide you hate them, you simply abandon them, and eventually git gc will reap them and get you your disk space back.

Use git diff --name-only master to show file list (or you can use the --stat flag to some more stats per file). This will show any diff files between current working tree, and the last place you left master (that seems to be 4 in your example). See more here .

Regarding the pathspec in git status - it justs filters the output to show only files in a specific directory.

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