4

I know that with the git command below I can list all my "remote" branches...

[someone@someone-pc somerepo]$ git ls-remote
Username for 'https://somegit.com': someone
Password for 'https://someone@somegit.com': 
From https://somegit.com/somepath/somerepo.git
32b73a94a2ef1be27298a7bbf6670670c9ad4892        HEAD
99cfe797ee2f4cd3fc12ea1aef8dc4ea0f3538c7        refs/heads/a_branch
687332d5e82436d806fea2c22ac5e8772e73b33a        refs/heads/b_branch
b1d82987dd87b99c505282cbcdf1d4c4d36be2d2        refs/heads/c_branch
32d4a73e686524e50a92880ddbd744d1363834bb        refs/heads/d_branch
097ad2a9a69399996f7e1864436d483b2a85e3c1        refs/heads/e_branch
1e92bb0aa448a840e04928272759a3941774575b        refs/heads/f_branch
32b73a94a2ef1be27298a7bbf6670670c9ad4892        refs/heads/master

QUESTION: Is there a way to list these branches ordered by creation date?

Thanks! =D


UPDATE:

To illustrate I would like something sorted like the gitlab branches list...

gitlab branches list

Eduardo Lucio
  • 1,771
  • 2
  • 25
  • 43
  • 3
    Branches do not have creation dates. (*Commits* have two timestamps, and a branch name identifies one commit, but clearly that's not what you're looking for.) – torek Oct 29 '19 at 18:50
  • 1
    Ah, maybe that *is* what you're looking for. I haven't used GitLab but that looks like it's telling you the age of one of the two timestamps of the commit to which the branch name points. So if someone makes a new commit now and pushes it to the server, the age of the new commit will be a few seconds, and the branch will move to the top. – torek Oct 29 '19 at 19:19
  • @torek How could I do what you describe? Maybe using some git command or even a bash "function"? Thanks! =D – Eduardo Lucio Oct 29 '19 at 19:25

1 Answers1

1

What git ls-remote does is call up the other Git—the one at the URL you see above—and ask it about its references: HEAD, branch names, tag names, and so on. But the only information that it sends are those names and the hash IDs.

As I noted in comments above, each commit—represented by a hash ID, which is sort of the commit's true name—has two timestamps in it.1 To obtain either or both time stamp, you must have the commit. So this means git ls-remote is not sufficient in general: you might not have the commits whose hash IDs you get from the other Git.

What you need to run first is git fetch, which starts the same way: it calls up some other Git and gets from it a list of their branches, tags, etc., and the hash IDs that each of those names represent. Then, for their branches, your Git will create or update your remote-tracking names: their master becomes your origin/master, for instance. Their develop becomes your origin/develop. Whatever names they have—refs/heads/* being the full form—your Git creates or updates your own corresponding refs/remotes/origin/* name. But before your Git can do that, your Git must obtain the commits themselves as well, so for any commits they have that you don't, that your Git needs, your Git gets those.

You may want to add --prune (git fetch -p for short) to direct your own Git to delete any remote-tracking name you have now that no longer corresponds to a branch in their Git. If you don't, you'll keep stale remote-tracking names forever (or until you explicitly prune them). This isn't really harmful so much as clutter-y.

Now you have all of their commits, plus any of your own you have not sent. You also have all of their names, changed into your remote-tracking names.

You can view these branches with git branch -r. The default sort order for git branch is alphabetic-within-group.2 But you can give a --sort=key option:3

git branch -r --sort=authordate

or:

git branch -r --sort=committerdate

which will sort based on the corresponding time stamp stored in the commit to which each remote-tracking name points.

Hence:

git fetch -p
git branch -r --sort=committerdate

should get you what you want (unless you want author date; see footnote 1).

(Aside: I like to configure fetch.prune to true in my per-user configuration, so that all fetches act like git fetch --prune always.)


1The two timestamps are the author timestamp and the committer timestamp. In many cases, both hold the same date-and-time anyway. A new commit in general gets both the same, and then if you copy the commit to a new and improved one, via git commit --amend or git rebase or any of the many other ways that can do that, the new and improved commit has the old commit's author information, and you-and-now as the committer information.

2Technically, it's more ASCII-betic, or UTF-8-betic, than alphabetic: a digit comes before uppercase, and uppercase comes before lowercase.

3Your git branch needs to be new enough to have the --sort option, which was introduced to git branch in Git 2.7. If your Git is older, consider using git for-each-ref.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I read everything you wrote, but I need to read more calmly to understand better. Soon I will give you feedback. Thanks! =D – Eduardo Lucio Oct 29 '19 at 20:21
  • 1
    Well, the two commands you might want are there in a block near the end. If you want the actual *age* of the commits, you'll need to add `--format` to `git branch`, which requires an even-newer Git version, or use `git for-each-ref`, which is klunkier to use than `git branch`. – torek Oct 29 '19 at 20:38
  • May help if I explain to you what I am really trying to do. I created a bash script to merge multiple branches with the aid of the Meld tool ( https://meldmerge.org/ ). I believe if we can obtain the output mentioned sorted by date of change or creation (whatever we can do) we can make the tool more efficient (will be easier and safer to use). To address what I am talking about, please note the code https://github.com/eduardolucioac/visual_git_merge/blob/master/vgm.bash#L259 . By the way... "vgm" is a free and open source code (BSD 3-Clause "New" or "Revised" License). Thanks! =D – Eduardo Lucio Oct 29 '19 at 20:40
  • 1
    Ah, I don't use any of those merge tools myself. However, note that the age of the tip commit of a branch is not going to correlate well to any merge issues you might have with the branch, in general. Merge issues occur because of significant drift from the *merge base* commit over time, so ideally you'd look at the symmetric difference of two branches and inspect the number and size of their internal commits, and/or simply compare the merge base to both branch tips. – torek Oct 29 '19 at 21:42
  • 1
    Remember also that Git can do an *octopus merge*, which doesn't really achieve anything you can't do by pairwise merging but is useful in some multiple-topic-branches cases to signify that this really was an all-into-one merge. – torek Oct 29 '19 at 21:43