# Copy the ports tree from a specific point in time using git



## Datapanic (Apr 6, 2021)

In the past, I've used this command to copy the ports tree from a specific date:


```
svn co -r'{2018-01-30}' https://svn.freebsd.org/ports/head /usr/local/poudriere/ports/HEAD-2018-01-30
```

With the move to git, I am at a loss for how to do the same thing with git.  I saw some advice about running *git log* and finding the revision number of the ports tree and then using *git checkout* but there's got to be an easier way to find the revision number of the ports tree.  

I want snapshots of the ports tree from specific times in the past to work with older versions of FreeBSD for my experimental setups.  There is a way to copy a quarterly branch, with poudriere it's like this, for example: 

```
poudriere ports -c -p HEAD-11 -m git+https -B 2020Q4
```

Any pro tips?  Thank you in advance!


----------



## SirDice (Apr 6, 2021)

Git - Revision Selection
					






					git-scm.com
				






Datapanic said:


> There is a way to copy a quarterly branch


They're branches. So they're easy to checkout. https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell


----------



## Jose (Apr 6, 2021)

Datapanic said:


> I saw some advice about running *git log* and finding the revision number of the ports tree and then using *git checkout* but there's got to be an easier way to find the revision number of the ports tree.


Git does not model repository history as an ordered list of revisions identified by monotonically increasing revision numbers. Git commits can be reordered; and their identifier, the commit hash, will change when they are. This sounds like a horrifically bad idea, but turns out to be insanely useful in practice.

It's not possible to do exactly what you've been doing with Git. Your local commit history could be different from the history in the repo you originally cloned. There are workarounds based on git-log(1) but they all suffer from various shortcomings. The Git way of doing what you've been doing is to use branches and tags.


Datapanic said:


> I want snapshots of the ports tree from specific times in the past to work with older versions of FreeBSD for my experimental setups.  There is a way to copy a quarterly branch, with poudriere it's like this, for example:
> 
> ```
> poudriere ports -c -p HEAD-11 -m git+https -B 2020Q4
> ```


One time

```
$ git clone https://git.freebsd.org/ports.git
Cloning into 'ports'...
remote: Enumerating objects: 982, done.
remote: Counting objects: 100% (982/982), done.
remote: Compressing objects: 100% (166/166), done.
remote: Total 4973679 (delta 931), reused 816 (delta 816), pack-reused 4972697
Receiving objects: 100% (4973679/4973679), 773.03 MiB | 25.23 MiB/s, done.
Resolving deltas: 100% (2997289/2997289), done.
Updating files: 100% (138821/138821), done.
 $ cd ports
```
First time using a particular quarterly branch

```
$ git switch -c 2021Q1 -t origin/2021Q1
Updating files: 100% (44201/44201), done.
Branch '2021Q1' set up to track remote branch '2021Q1' from 'origin'.
Switched to a new branch '2021Q1'
```
Update a quarterly branch you're already tracking

```
$ git switch 2021Q1
Already on '2021Q1'
Your branch is up to date with 'origin/2021Q1'.
 $ git pull
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (11/11), 223.79 KiB | 4.86 MiB/s, done.
From https://git.freebsd.org/ports
   64d5a3b23aca..d751a7ccc7bc  main       -> origin/main
Already up to date.
```


----------



## memreflect (Apr 6, 2021)

From a git perspective, `svn co -r'{2018-01-30}' ...` looks underspecified.  Sure, you want anything up to and including _2018-01-30_, but does that mean you also want check-ins from _2018-01-31 02:00:00 +0200_?  Technically that's still _2018-01-30_ to someone in New York, so should any check-ins with that timestamp should still be included, even if you're in Tokyo yourself?

That said, git-log(1) and git-rev-list(1) both accept two relevant options:

```
--max-count=<n>
--before=<date>
```
<date> should really be <timestamp> since results are a bit unpredictable with just a date like 2018-01-30; you can use `--before=2018-01-30T23:59:59-1200` for example (drop the -1200 and all commits with a committer date prior to and including 23:59:59 in your local time zone will be included).

If you're looking through a commit log and dislike how the time zones vary between commits, see `--date=<format>` in git-log(1).  I actually used `git config --global log.date iso-local` to permanently make all dates output as local times in my system's time zone in an ISO 8601-like format.

Lastly, you may be confused by the default output from git-log(1), which only lists the author date.  `--before=<date>` operates on the committer date, which you can see using `--pretty=fuller`.  Basically, if the author date of a commit is _2018-01-30_, but the committer date is _2018-02-03_, you won't see that commit because `--before=2018-01-30` excludes the commit from _2018-02-03_.

Or you can just adjust to branches like origin/2021Q1 and/or tags like release-12.2.0.


----------

